-
Notifications
You must be signed in to change notification settings - Fork 29.8k
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
stream: support Uint8Array input to methods #11608
Conversation
eb79285
to
bbdafd7
Compare
lib/stream.js
Outdated
} | ||
|
||
const version = process.version.substr(1).split('.'); | ||
if (version[0] <= 0 && version[1] < 12) { |
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.
When would the major version be less than zero?
Also, why are we adding an explicit check for such old versions of node (v0.10 and older) if they're no longer supported?
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.
Because readable-stream
still supports them and removing that support would at least be a breaking change…
When would the major version be less than zero?
Never, I can update this to ===
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.
Ugh... I can't help but think readable-stream
should polyfill this instead of node core...
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.
If @nodejs/streams is willing to do that I’m all for it.
doc/api/stream.md
Outdated
- version: v6.0.0 | ||
pr-url: https://github.com/nodejs/node/pull/6170 | ||
description: Passing `null` as the `chunk` parameter will always be | ||
considered invalid now, even in object mode. | ||
--> | ||
|
||
* `chunk` {String|Buffer} The data to write | ||
* `chunk` {String|Buffer|Uint8Array} The data to write |
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.
A bit unrelated, but this doesn't match the chunk
description of .end()
which is confusing, specifically the 'any' part.
doc/api/stream.md
Outdated
--> | ||
|
||
* `chunk` {Buffer|String} Chunk of data to unshift onto the read queue | ||
* `chunk` {Buffer|Uint8Array|String} Chunk of data to unshift onto the |
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.
Ditto here about the chunk
description and missing 'any' I think.
doc/api/stream.md
Outdated
|
||
* `chunk` {Buffer|Null|String} Chunk of data to push into the read queue | ||
* `chunk` {Buffer|Uint8Array|Null|String} Chunk of data to push into |
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.
Another unrelated nit: it seems like 'Null' should be all lowercase since there is no such constructor.
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.
By that logic String should also be lowercase since it doesn't mean the String constructor.
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.
@seishun I agree, but I recall others possibly arguing for the uppercase version in the past? There might need to be changes to the doc tool...
@mscdex addressed your comments, PTAL |
@seishun right… should’ve seen that. done! |
fe74aee
to
8c68763
Compare
Overall this LGTM but I'd definitely prefer more attention and signoff from @nodejs/streams folks |
|
||
// Internal utilities | ||
try { | ||
Stream._isUint8Array = process.binding('util').isUint8Array; |
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.
Maybe move this into internal/util
?
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.
@joyeecheung The thing is that the streams modules can’t really unconditionally rely on internal modules because they are also exported as https://github.com/nodejs/readable-stream. @mscdex expressed a preference for having this code polyfilled on the readable-stream
side and I agree, but ultimately that’s @nodejs/streams’ call …
(Please let me know if I’m misunderstanding you!)
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.
Oh yes, forgot about the vendoring out part :) Nevermind then!
Before LGTMing this I would like to consider if we have alternative fast approaches here to avoid I'm not 100% on board with accepting Regarding |
What are the semantics that you would like to see in such an alternative?
Could you give an example for that? I tried to specifically avoid that.
Why would they be affected by this change?
What does readable-stream use as
This only hits when the input is not already a
Does that mean skipping this PR for readable-stream in some way? |
To some extent, I do not care. I care about the speed improvement this brings without breaking any existing code, plus
Here is the difference: class MyTransform {
constructor(opts) {
super(opts)
}
transform(chunk, enc, cb) {
// chunk can be both a UInt8Array or a Buffer
// because this stream can be set in objectMode or not
cb()
})
} I know it might be a very narrow case, but there is a lot of code where
What about return Object.prototype.toString.call(obj) === '[object Uint8Array]';
https://github.com/feross/buffer
Yes |
b282929
to
5105ec0
Compare
Thanks for pointing that out, that was a bug in this PR and not intentional. Fixed!
The
Right, this might indeed get tricky for platforms that don’t have |
Looking into the |
5105ec0
to
0e7fb4b
Compare
Just read @joyeecheung’s comment in #11690 (review) and checked the benchmarks on
So this would still seem okay from a performance viewpoint on V8 5.8. But anyway, I’m not proposing this change because of performance but because I think Uint8Array support is actually valuable for Node’s API. |
@addaleax So, I'd like to have the speed boost in core, but on the other side I am not 100% in with the support of UInt8Array. What's the use case to support IMHO, we should expose |
@mcollina So … for the other modules where I’m doing this, it makes sense because:
I realize that these things don’t apply to streams the same way they do for other parts of the API, but I’d still say that there’s no real reason not to support Uint8Arrays. Maybe other @nodejs/collaborators have some thoughts to offer on whether we should do this, or a general 👍/👎 feeling?
We could expose |
Not really part of the discussion anymore, just fyi, I looked the into performance of |
@addaleax all the streams API speaks buffers. Specially the I think we should talk about this with the rest of @nodejs/streams. |
Right – that’s kind of my point. 😄 It makes sense for the rest of Node core’s API, therefore it would be consistent and less confusing if that was the same for streams.
Yeah, of course, all the APIs that give back
Yes! :) |
So it might make sense from core's point of view, but not on
In Node.js, yes. However the whole streams ecosystem does not rely on |
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.
LGTM
@addaleax this was approved during the WG meeting in Berlin! Would you mind updating the conflicting doc and land this? :) |
@addaleax can you rebase? I think we can release this. |
0e7fb4b
to
ece3234
Compare
ece3234
to
6573670
Compare
Landed in 9f610b5 |
PR-URL: #11608 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Fantastic! |
PR-URL: #11608 Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
streams
(Yes, those are improvements, not losses… I find it odd that
instanceof
is so heavy compared toisUint8Array
, but this is what the benchmarks say, and I won’t complain. d088360 is themaster
head at the time of writing.)@nodejs/streams