streams
streams copied to clipboard
define semantics of {source,sink}.finally()
Discussion at https://github.com/whatwg/streams/issues/617#issuecomment-262220474 https://github.com/whatwg/streams/issues/617#issuecomment-262729169 https://github.com/whatwg/streams/issues/620#issuecomment-263174269 and https://github.com/whatwg/streams/issues/628#issuecomment-266778598 mentioned the need for adding a finally() method to underlyingSink (and underlyingSource?) at some point in the future.
It sounds like the ideas for finally are
- called after
abort,close, (andcancelandflush?) etc, are called (after their returned promises fulfill?) - called with any uncaught errors thrown synchronously by any method, or thrown by strategySize, or thrown by the implementation when e.g. strategy.size() returns NaN
- also called with the rejection reason of any rejected promise that causes the stream to become errored
Proposed arguments were finally(why, reason), where why is e.g. the string 'close' or 'abort', but what about all the other causes for finally to be called? What would 'why' be for an invalid queueing strategy return value causing a RangeError?
Should it stay as two arguments like that, or one object analogous to an IteratorResult?
Thanks for filing this.
My plan for why was to add a few more reasons, such as 'error' for when controller.error() was called. I intended to use 'exception' for when a sink/source method threw an exception, but I realise now that we need to distinguish exceptions from strategy.size().
Could you explain a bit more what the benefit would be of switching to one argument?
I think sometimes we will need to call finally() asynchronously because we are in a bad state and can't deal with re-entrancy issues. It might be good to guarantee that we always call finally() asynchronously, so that sink code can be sure that none of its own code is executing synchronously. On the other hand, it may be sufficient to guarantee that none of the sink methods are on the stack.
Everything applies the same to ReadableStream and TransformStream. WritableStream is just what's on my mind right now.