-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merge http2 stream & net socket #19527
Changes from 13 commits
b037232
efa0f4f
19aedde
5c8eb75
92e4f71
babe858
27818c4
0144de4
e4365d6
560635d
833c52a
fcfd8d3
43b912d
5055714
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
'use strict'; | ||
|
||
const { Buffer } = require('buffer'); | ||
const errors = require('internal/errors'); | ||
const { WriteWrap } = process.binding('stream_wrap'); | ||
|
||
const errnoException = errors.errnoException; | ||
|
||
function handleWriteReq(req, data, encoding) { | ||
const { handle } = req; | ||
|
||
switch (encoding) { | ||
case 'buffer': | ||
return handle.writeBuffer(req, data); | ||
case 'latin1': | ||
case 'binary': | ||
return handle.writeLatin1String(req, data); | ||
case 'utf8': | ||
case 'utf-8': | ||
return handle.writeUtf8String(req, data); | ||
case 'ascii': | ||
return handle.writeAsciiString(req, data); | ||
case 'ucs2': | ||
case 'ucs-2': | ||
case 'utf16le': | ||
case 'utf-16le': | ||
return handle.writeUcs2String(req, data); | ||
default: | ||
return handle.writeBuffer(req, Buffer.from(data, encoding)); | ||
} | ||
} | ||
|
||
function createWriteWrap(handle, oncomplete) { | ||
const req = new WriteWrap(); | ||
|
||
req.handle = handle; | ||
req.oncomplete = oncomplete; | ||
req.async = false; | ||
|
||
return req; | ||
} | ||
|
||
function writevGeneric(self, req, data, cb) { | ||
const allBuffers = data.allBuffers; | ||
let chunks; | ||
let i; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you restore these as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cc @bmeurer There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mcollina I might be wrong, but I think it shouldn’t make a difference for variables that are at the top level of a function? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. const or let have some overhead in Node 8 and 9 in tight loops such as this one. I’m not sure if this still the case with current master. I’d prefer if this refactoring was separated from changing from var to const/let. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mcollina makes sense, i'll change them back to |
||
if (allBuffers) { | ||
chunks = data; | ||
for (i = 0; i < data.length; i++) | ||
data[i] = data[i].chunk; | ||
} else { | ||
chunks = new Array(data.length << 1); | ||
for (i = 0; i < data.length; i++) { | ||
const entry = data[i]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you make this a var as it was? |
||
chunks[i * 2] = entry.chunk; | ||
chunks[i * 2 + 1] = entry.encoding; | ||
} | ||
} | ||
const err = req.handle.writev(req, chunks, allBuffers); | ||
|
||
// Retain chunks | ||
if (err === 0) req._chunks = chunks; | ||
|
||
if (err) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: it should be ok to use an |
||
return self.destroy(errnoException(err, 'write', req.error), cb); | ||
} | ||
|
||
function writeGeneric(self, req, data, encoding, cb) { | ||
const err = handleWriteReq(req, data, encoding); | ||
|
||
if (err) | ||
return self.destroy(errnoException(err, 'write', req.error), cb); | ||
} | ||
|
||
module.exports = { | ||
createWriteWrap, | ||
writevGeneric, | ||
writeGeneric | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -46,12 +46,17 @@ const { TCP, constants: TCPConstants } = process.binding('tcp_wrap'); | |
const { Pipe, constants: PipeConstants } = process.binding('pipe_wrap'); | ||
const { TCPConnectWrap } = process.binding('tcp_wrap'); | ||
const { PipeConnectWrap } = process.binding('pipe_wrap'); | ||
const { ShutdownWrap, WriteWrap } = process.binding('stream_wrap'); | ||
const { ShutdownWrap } = process.binding('stream_wrap'); | ||
const { | ||
newAsyncId, | ||
defaultTriggerAsyncIdScope, | ||
symbols: { async_id_symbol } | ||
} = require('internal/async_hooks'); | ||
const { | ||
createWriteWrap, | ||
writevGeneric, | ||
writeGeneric | ||
} = require('internal/stream_base_commons'); | ||
const errors = require('internal/errors'); | ||
const { | ||
ERR_INVALID_ADDRESS_FAMILY, | ||
|
@@ -740,38 +745,15 @@ Socket.prototype._writeGeneric = function(writev, data, encoding, cb) { | |
return false; | ||
} | ||
|
||
var req = new WriteWrap(); | ||
req.handle = this._handle; | ||
req.oncomplete = afterWrite; | ||
req.async = false; | ||
var err; | ||
|
||
if (writev) { | ||
var allBuffers = data.allBuffers; | ||
var chunks; | ||
var i; | ||
if (allBuffers) { | ||
chunks = data; | ||
for (i = 0; i < data.length; i++) | ||
data[i] = data[i].chunk; | ||
} else { | ||
chunks = new Array(data.length << 1); | ||
for (i = 0; i < data.length; i++) { | ||
var entry = data[i]; | ||
chunks[i * 2] = entry.chunk; | ||
chunks[i * 2 + 1] = entry.encoding; | ||
} | ||
} | ||
err = this._handle.writev(req, chunks, allBuffers); | ||
|
||
// Retain chunks | ||
if (err === 0) req._chunks = chunks; | ||
} else { | ||
err = createWriteReq(req, this._handle, data, encoding); | ||
} | ||
let ret; | ||
const req = createWriteWrap(this._handle, afterWrite); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you make these vars? |
||
if (writev) | ||
ret = writevGeneric(this, req, data, cb); | ||
else | ||
ret = writeGeneric(this, req, data, encoding, cb); | ||
|
||
if (err) | ||
return this.destroy(errnoException(err, 'write', req.error), cb); | ||
// Bail out if handle.write* returned an error | ||
if (ret) return ret; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Given the note above re: changed semantics for http2, I would rather we just test for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since @addaleax requested this related change, I rescind the feedback above. That said, a comment should be left indicating that Since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @apapirovski Just for context, I talked with @aks- about this and I don’t think it’s a good permanent solution anyway, but doing more might require some changes to the But yes, a comment here would be very helpful There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there was a suggestion to leave a comment somewhere saying that this line is only run in case of an error? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done :D |
||
|
||
this._bytesDispatched += req.bytes; | ||
|
||
|
@@ -794,34 +776,6 @@ Socket.prototype._write = function(data, encoding, cb) { | |
this._writeGeneric(false, data, encoding, cb); | ||
}; | ||
|
||
function createWriteReq(req, handle, data, encoding) { | ||
switch (encoding) { | ||
case 'latin1': | ||
case 'binary': | ||
return handle.writeLatin1String(req, data); | ||
|
||
case 'buffer': | ||
return handle.writeBuffer(req, data); | ||
|
||
case 'utf8': | ||
case 'utf-8': | ||
return handle.writeUtf8String(req, data); | ||
|
||
case 'ascii': | ||
return handle.writeAsciiString(req, data); | ||
|
||
case 'ucs2': | ||
case 'ucs-2': | ||
case 'utf16le': | ||
case 'utf-16le': | ||
return handle.writeUcs2String(req, data); | ||
|
||
default: | ||
return handle.writeBuffer(req, Buffer.from(data, encoding)); | ||
} | ||
} | ||
|
||
|
||
protoGetter('bytesWritten', function bytesWritten() { | ||
var bytes = this._bytesDispatched; | ||
const state = this._writableState; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be nice to have this done for
writev
too :)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@addaleax done 👍