-
Notifications
You must be signed in to change notification settings - Fork 161
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
Ensure the JS thread doesn't have to get hit when piping two streams to each other #97
Comments
One important question is if we actually want to support code like the above? My concern is that it makes it very easy to create footguns where you suddenly get dramatically slower performance for something that is seemingly a harmless no-op. For example var oldWrite = fsStream.write;
fsStream.write = function (chunk) {
if (debug)
console.log("saved", chunk);
oldWrite.apply(this, arguments);
}; or even fsStream.write = fsStream.write.bind(fsStream) I don't know the answer. But it's not obvious to me that it's beneficial that overriding |
The issue is that if |
This is important, but I don't think we need to enable replacing We should also clearly specify how pipeTo determines whether to use such an offloaded/platform piping or call JS function. |
The base pipeTo should always follow the specified algorithm; subclasses can always override it with more specialized versions. |
I meant how to check if dest can receive piped data out of JS thread or not. If dest's write is overridden by JS code, it needs to be run in JS thread. Otherwise, we could do some optimized offloaded pipe depending on dest's type. |
Well, my understanding of @sicking and others' ideas was that if you did certain special combinations, e.g. XHRStream.prototype.pipeTo = function (dest, options) {
if (dest.[[InternalStreamType]] === "file") {
cppBindings.pipeTogetherOffMainThread(this, dest, options);
} else {
ReadableStream.prototype.pipeTo.apply(this, arguments);
}
}; |
Er, wait, I realize that doesn't address what you're talking about. Yes, I agree, determining clearly what the criteria are is important... the spec should provide some hook other specs can use so that they can do e.g. XHRStream.prototype.pipeTo = function (dest, options) {
if (dest.[[InternalStreamType]] === "file" && isUndisturbed(dest)) {
cppBindings.pipeTogetherOffMainThread(this, dest, options);
} else {
ReadableStream.prototype.pipeTo.apply(this, arguments);
}
}; Here This is all of course assuming our solution is indeed of the caching-write flavor described. Other solutions would be some kind of double-dispatch, which we could conceivably even bake into the base spec... e.g. ReadableStream.pipeTo = function (dest, options) {
if (dest.pipeFrom(this)) {
// successfully hooked up at the OS level; all done
} else {
// the dest had no special way of hooking itself up to `this`, so do the usual algorithm
}
}; |
Right. Thanks. One more point I'd like to clarify is how dest's |
I like the concept of I also agree it would not be an exposed function, and would like to have it be well defined in the spec - I can see other specs needing this behavior documented and will be able to reference this spec for a definitive algorithm. @tyoshino - I don't quite understand why the |
@ferasm |
/cc @Gozala |
@yutakahirano pointed out that not only for See also w3c/ServiceWorker#413 and w3c/ServiceWorker#452 |
I also think that we really need the ability to send a ReadableStream or WritableStream to another thread using worker.postMessage({ theStream: stream }) or port.postMessage({ theStream: stream }). In that case too we should make sure to not hit more threads than needed. |
@sicking Is what you're proposing a Streams API based pipe for communication between workers/windows? |
I'll avoid using the word "pipe" since it means different things to different people. What I mean is that if I get a ReadableStream or WriableStram from something like |
@sicking Is the In the main thread:
In the worker thread:
|
Yes. Just like with any other transferable objects. What's the advantage of the |
And let me know if this discussion should maybe be done as a separate issue? |
Sorry, I hadn't give it much thoughts yet. A little more study follows: The streams are so sophisticated than ArrayBuffer (just buffer. no state), String, Blob (immutable. no state), etc. I think we don't want to accept general streams. But even byte streams, string streams, etc. have states. In
Thinking about (1), as we have If we want to realize (2), we need to take |
Created. #244 |
Quick update on this (old) issue: this is one of the highest priorities of the current design, pioneered with the stream reader concept. The only missing piece is a similar stream writer for writable streams. Once we have that in place this issue is done. We are very much on track though and have been designing the system around this goal. |
This is happening at #462 |
E.g., an XHR stream to a file system stream,
xhrStream.pipeTo(fsStream)
.As-is, there might be a problem if e.g. the user does
after the pipe is already set up. The implementation would have to detect this and start routing data to the main thread, which kind of sucks.
A possible fix would be caching the value of
dest.write
at the top ofpipeTo
./cc @sicking
The text was updated successfully, but these errors were encountered: