Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
http2: making sending to the socket more efficient
  • Loading branch information
jasnell committed Sep 29, 2017
commit 0b943c6554006b263ea41d4687459d20769cb0a0
14 changes: 12 additions & 2 deletions benchmark/http2/write.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,27 @@ const PORT = common.PORT;
const bench = common.createBenchmark(main, {
streams: [100, 200, 1000],
length: [64 * 1024, 128 * 1024, 256 * 1024, 1024 * 1024],
size: [100000]
}, { flags: ['--no-warnings'] });

function main(conf) {
const m = +conf.streams;
const l = +conf.length;
const s = +conf.size;
const http2 = require('http2');
const server = http2.createServer();
server.on('stream', (stream) => {
stream.respond();
stream.write('ü'.repeat(l));
stream.end();
let written = 0;
function write() {
stream.write('ü'.repeat(s));
written += s;
if (written < l)
setImmediate(write);
else
stream.end();
}
write();
});
server.listen(PORT, () => {
bench.http({
Expand Down
63 changes: 46 additions & 17 deletions src/node_http2_core-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -478,25 +478,54 @@ inline void Nghttp2Session::SendPendingData() {
// will not be usable.
if (IsDestroying())
return;
const uint8_t* data;
ssize_t len = 0;
size_t ncopy = 0;
uv_buf_t buf;
AllocateSend(SEND_BUFFER_RECOMMENDED_SIZE, &buf);
while (nghttp2_session_want_write(session_)) {
len = nghttp2_session_mem_send(session_, &data);
CHECK_GE(len, 0); // If this is less than zero, we're out of memory
// While len is greater than 0, send a chunk
while (len > 0) {
ncopy = len;
if (ncopy > buf.len)
ncopy = buf.len;
memcpy(buf.base, data, ncopy);
Send(&buf, ncopy);
len -= ncopy;
CHECK_GE(len, 0); // This should never be less than zero

uv_buf_t dest;
AllocateSend(SEND_BUFFER_RECOMMENDED_SIZE, &dest);
size_t destLength = 0; // amount of data stored in dest
size_t destRemaining = dest.len; // amount space remaining in dest
size_t destOffset = 0; // current write offset of dest

const uint8_t* src; // pointer to the serialized data
ssize_t srcLength = 0; // length of serialized data chunk

// While srcLength is greater than zero
while ((srcLength = nghttp2_session_mem_send(session_, &src)) > 0) {
DEBUG_HTTP2("Nghttp2Session %s: nghttp2 has %d bytes to send\n",
TypeName(), srcLength);
size_t srcRemaining = srcLength;
size_t srcOffset = 0;

// The amount of data we have to copy is greater than the space
// remaining. Copy what we can into the remaining space, send it,
// the proceed with the rest.
while (srcRemaining > destRemaining) {
DEBUG_HTTP2("Nghttp2Session %s: pushing %d bytes to the socket\n",
TypeName(), destRemaining);
memcpy(dest.base + destOffset, src + srcOffset, destRemaining);
destLength += destRemaining;
Send(&dest, destLength);
destOffset = 0;
destLength = 0;
srcRemaining -= destRemaining;
srcOffset += destRemaining;
destRemaining = dest.len;
}

if (srcRemaining > 0) {
memcpy(dest.base + destOffset, src + srcOffset, srcRemaining);
destLength += srcRemaining;
destOffset += srcRemaining;
destRemaining -= srcRemaining;
srcRemaining = 0;
srcOffset = 0;
}
}

if (destLength > 0) {
DEBUG_HTTP2("Nghttp2Session %s: pushing %d bytes to the socket\n",
TypeName(), destLength);
Send(&dest, destLength);
}
}

// Initialize the Nghttp2Session handle by creating and
Expand Down