-
-
Notifications
You must be signed in to change notification settings - Fork 33.8k
stream: allow typed arrays to be written and read #22427
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
Conversation
|
on second thought, the |
lib/stream.js
Outdated
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.
This is going to be pretty slow. Surely there is a better way...
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.
Will .indexOf() be faster? Open to other suggestions as well.
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.
Can't we just use something like ArrayBuffer.isView()? It seems to be available since at least node v4. The reason the string check was used before was because we were explicitly checking for only Uint8Array.
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.
On util.types are a lot of checks that can be used as well.
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.
@BridgeAR the relevant function from util.types is already being used earlier in this file if it exists. This implementation here is used if both the function from util.types and the function from the util binding are not available.
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.
@mscdex so ArrayBuffer.isView() could still be available, even though util.types and util binding are not available?
In other PRs dealing with typed arrays, i have been using:
const { isArrayBufferView } = require('internal/util/types');
Same can be used here too?
Wasn't sure whether compatibility with 0.x versions was specifically required here, and how to add that support.
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.
so ArrayBuffer.isView() could still be available, even though util.types and util binding are not available?
My guess is that a string-based check was used previously for better compatibility with other, non-node platforms that use the same streams interface? I do not know for sure. Perhaps @addaleax might remember why they added that kind of implementation?
EDIT: judging by the comments from earlier in this file, it could also be useful for node v6.x, which does not have require('util').types, process.binding('util').isArrayBufferView, or require('internal/util/types').
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.
So i'm guessing current PR stays put?
Or is there any merit in adding a patch of this sort:
diff --git a/lib/stream.js b/lib/stream.js
index c6861b3464..58aab7c16d 100644
--- a/lib/stream.js
+++ b/lib/stream.js
@@ -42,6 +42,15 @@ Stream.finished = eos;
Stream.Stream = Stream;
// Internal utilities
+try {
+ const { isArrayBufferView } = require('internal/util/types');
+ if (typeof isArrayBufferView === 'function') {
+ Stream._isArrayBufferView = isArrayBufferView;
+ }
+} catch (e) {
+}
+
+if (!Stream._isArrayBufferView) {
try {
const types = require('util').types;
if (types && typeof types.isArrayBufferView === 'function') {
@@ -53,6 +62,7 @@ try {
}
} catch (e) {
}
+}
if (!Stream._isArrayBufferView) {
Stream._isArrayBufferView = function _isArrayBufferView(obj) {
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.
@SirR4T That's more or less the exact same thing that's being done below that with require('util').types. I still think using ArrayBuffer.isView() as the fallback is probably best. I suppose the function could be cached at startup like internal/util/types does.
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.
Updated to use ArrayBuffer.isView. Although do verify, if simply having it in a constant will cache it? Or should the const isTypedArray be moved to module scope?
Also, shouldn't we be checking for existence of ArrayBuffer.isView first, and then be falling back to other methods (util.types)?
lib/stream.js
Outdated
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.
These comments should be removed
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.
done.
lib/stream.js
Outdated
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.
On util.types are a lot of checks that can be used as well.
lib/stream.js
Outdated
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.
This will likely not work with anything besides Uint8Array. So any other TypedArray would fail.
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.
updated ._typedArrayToBuffer to use Buffer.from().
lib/stream.js
Outdated
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.
This needs to be updated to check for the correct function.
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.
done.
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.
Hi @BridgeAR , does this look ok, for _typedArrayToBuffer()?
lib/stream.js
Outdated
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.
the Buffer.prototype.slice() would have made a different Buffer. With Buffer.from(), the underlying memory will still be shared. Will that be a problem?
lib/stream.js
Outdated
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, in this case we don't actually need to do any caching. I think we can just do
Stream._isArrayBufferView = ArrayBuffer.isView;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.
done.
fdcd563 to
38fd0fc
Compare
|
rebased against master. does that warrant a new CI? |
|
Hi @mscdex , sorry for the commit and CI noise, but I had rebased this branch against master, after the earlier CI run had completed. For this to be merged in, should another CI run be initiated? Also, kind of off topic: |
|
I've added the dont-land-on-6 and dont-land-on-8 labels out of caution. |
lib/stream.js
Outdated
| Stream._isArrayBufferView = types.isArrayBufferView; | ||
| } else { | ||
| // This throws for Node < 4.2.0 because there's no util binding and | ||
| // returns undefined for Node < 7.4.0. |
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.
This comment would need to be updated. When has isArrayBufferView been added?
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.
v7.4.0.
doc/api/stream.md
Outdated
| * `chunk` {Buffer|TypedArray|DataView|string|null|any} Chunk of data to push | ||
| into the read queue. For streams not operating in object mode, `chunk` must | ||
| be a string, `Buffer` or `Uint8Array`. For object mode streams, `chunk` may | ||
| be any JavaScript value. |
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.
I guess this sentence is not up-to-date. It's not just string, Buffer or Uint8Array anymore.
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.
True, but the typed arrays and data views can be passed received only in object mode. So thought that the current statement still remains true.
It might be better to explicitly document this behaviour though. Any thoughts on the same?
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 I misunderstood this PR then. I thought the whole point of this is to support all TypedArray and DataView in binary mode.
This looks like from looking at the code as !state.objectMode && Stream._isArrayBufferView works when objectMode is `false.
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.
yea... I wasn't sure of the behaviour we required here, which is why I had raised the PR with a caveat.
The PR introducing support for Uint8Array in streams, too, asserts a similar behaviour, so I had let this PR follow similarly.
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.
Exactly. Still, this PR make accepting TypedArray and DataView everywhere so it should be reflected in the docs.
lib/stream.js
Outdated
| return Buffer.from(chunk.buffer, chunk.byteOffset, chunk.byteLength); | ||
| }; | ||
| } | ||
| } |
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.
I think we can clean up this whole file. As long as it exports the two functions we need, it's ok to not have all those checks. readable-stream@3 supports Node 6+ anyway.
doc/api/stream.md
Outdated
| * `chunk` {Buffer|TypedArray|DataView|string|null|any} Chunk of data to push | ||
| into the read queue. For streams not operating in object mode, `chunk` must | ||
| be a string, `Buffer` or `Uint8Array`. For object mode streams, `chunk` may | ||
| be any JavaScript value. |
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.
Exactly. Still, this PR make accepting TypedArray and DataView everywhere so it should be reflected in the docs.
38fd0fc to
865f456
Compare
|
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.
this header is not required
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.
the whole point of this change is see how they work with objectMode: false.
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.
this needs to be objectMode: false. Also everywhere else.
|
@mcollina : pushed changes with One test is still failing, which raises this question: how should |
Are you sure? Can you please add some checks in the tests that everything that is emitted/returned by
I think this is why you need the conversion that you have commented out. |
|
ping @SirR4T. |
|
Currently swamped at work, will look into this whenever I find some time.
Most likely within the next two weeks.
Sarat.
…On Wed, Oct 3, 2018 at 2:01 PM Denys Otrishko ***@***.***> wrote:
ping @SirR4T <https://github.com/SirR4T>.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#22427 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB8IMLS1rZyf_9rPyjgl5jI0WFR1C_jbks5uhHXVgaJpZM4WFUJ6>
.
|
06b494a to
dbfcade
Compare
|
@SirR4T Ping, any update on this? |
|
fixed the merge conflicts for now, but if someone could guide me on correcting the test cases, would appreciate the help. |
9f31601 to
7841da2
Compare
| write: common.mustCall((chunk, encoding, cb) => { | ||
| assert(!(chunk instanceof Buffer)); | ||
| assert(ArrayBuffer.isView(chunk)); | ||
| assert.deepStrictEqual(chunk, nthWrittenBuffer(n++)); |
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.
Instances of Buffer could not be deepStrictEqual to those of TypedArray, could they?
Maybe try:
assert.deepStrictEqual(Buffer.from(chunk.buffer, chunk.byteOffset, chunk.length), nthWrittenBuffer(n++));|
@SirR4T what is the status here? |
8ae28ff to
2935f72
Compare
|
Given that this is out of date and there has been no activity in over a year, closing. Can reopen if it is picked back up again |
Checklist
make -j4 test(UNIX), orvcbuild test(Windows) passesPartially fixing #1826
Caveat
TypedArrayscan be written, now, but in non-objectMode, the.write()method still receives rawBuffers.I'm not completely sure that is the behaviour we want, but I'm willing to work towards fixing it, with some mentoring.