Skip to content
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

Synchronous queue draining for WritableStream #465

Closed
tyoshino opened this issue Jun 1, 2016 · 4 comments
Closed

Synchronous queue draining for WritableStream #465

tyoshino opened this issue Jun 1, 2016 · 4 comments

Comments

@tyoshino
Copy link
Member

tyoshino commented Jun 1, 2016

A WritableStream invokes its underlying sink's write() method for each chunk in its queue. This completes only asynchronously on invocation of the fulfillment callback set to the promise returned by the write() call. This means that one microtask is required to process each chunk.

We could change this to allow for synchronous draining by introducing an interface similar to the byobRequest interface we've adopted for responding to BYOB reading in the underlying source of ReadableStream.

It'll be like:

  • when a new chunk is enqueued, write() (or could be renamed to push()) is invoked to notify the sink of that there're some chunks available for processing (redundant invocation is still prevented by the _writing flag).
  • WritableStreamDefaultController has a getter named writeRequest() which has get chunk() and ack() method.
  • Calling ack() tells the WritableStream to fulfill the promise returned on write() call on the WritableStream.
  • Once ack() is called, writeRequest() is updated to represent the next chunk in the queue. If there's no chunk, it returns undefined.
@tyoshino
Copy link
Member Author

tyoshino commented Jun 1, 2016

Hmm. WritableStream.write() synchronously invokes underlyingSink.write(). With this optimization, sequential multiple write() calls are processed by:

  • ws.write() -> sink.write()
  • ws.write(), ws.write(), ... -> pending until the fulfillment callback is invoked
  • sink.write() processes chunks enqueued by the 2nd and later ws.write() calls

Looks weird. But there's similar behavior in ReadableStream too? pull is invoked sync to read() and we can call rscontroller.enqueue() multiple times synchronously but they're delivered to the data consumer in async manner.

@domenic
Copy link
Member

domenic commented Jun 1, 2016

I am not too worried about the microtask delay; I feel like we discovered a while ago that wasn't a very important part of things. So I think for the default controller the current design is good.

However, I do think we should consider "BYOB" writable streams (I guess in this case it's "keep your own buffer"? KYOB?) with an efficient interface. I'm not sure exactly what that looks like or how it works. I guess that ties in to #329 and #325.

@domenic
Copy link
Member

domenic commented Aug 4, 2016

Let's close this as I think our current design is pretty good.

@domenic domenic closed this as completed Aug 4, 2016
@tyoshino
Copy link
Member Author

tyoshino commented Aug 4, 2016

OK. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

2 participants