- From: Domenic Denicola <notifications@github.com>
- Date: Thu, 15 Jan 2015 12:32:28 -0800
- To: whatwg/streams <streams@noreply.github.com>
- Message-ID: <whatwg/streams/issues/263@github.com>
This is mostly for discussion, as it is probably not a bug problem. But I wanted to lay it out. In the review of some reader fixes at https://github.com/whatwg/streams/pull/262#discussion_r22993414 @yukatahirano pointed what you could see as a potential waiting -> waiting transition. It occurs even without readers so I think we can leave them out of the discussion. An example: ```js stream.ready.then(() => console.log(stream.state)); // enqueue a chunk stream.read(); // will log "waiting" ``` Normally we try to enforce that when `ready` fulfills, the state is no longer `"waiting"`, since kind of the point of `ready` is to tell you when you're done waiting. This kind of usage is atypical though so it is not too problematic. Usually you do not know, until `ready` fulfills, that the stream has become `"readable"`. In this example we are using external knowledge---namely, the fact that on the previous line we enqueued in the stream---to figure it out. If we were to think about mitigating this, the options don't seem great: - Delay fulfilling `ready` for a microtask; at that time check if state is now `"waiting"` (due to queue drainage) and if so don't fulfill `ready`. This kind of just shuffles the problem around though: someone could just do `Promise.resolve().then(() => stream.read())` to "fool" the check by waiting until after it happens. - Make everything async: i.e., don't actually do the enqueue until a microtask later. So if you enqueue, the chunk will not be immediately available for `read()`. We should be able to schedule the availability of the chunk such that it happens immediately before `ready` fulfills, thus avoiding any possibility of interleaving as in the above possibility. - Embrace sync instead of async: stop using promises and use some sort of [zalgo-esque](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) callback system that synchronously notifies of availability. I am not sure why I am even mentioning this. I just realized there is another way to encounter a `"waiting"` state in the `ready` handler, even when doing "normal" usage: ```js stream.ready.then(() => { console.log(stream.state); stream.read(); }); // in some other part of the code, perhaps: stream.ready.then(() => { console.log(stream.state); }); // enqueue a single chunk // will log "readable", "waiting" ``` basically any multi-consumer scenario has the potential to see "waiting". So in general maybe the takeaway here is to add a quick note that usually the state will be non-"waiting", but it's possible that it will be "waiting" if someone drained the queue between the transition happening and your fulfillment handler being called. I still think it's worthwhile to preserve the pseudo-invariant in other cases though. --- Reply to this email directly or view it on GitHub: https://github.com/whatwg/streams/issues/263
Received on Thursday, 15 January 2015 20:33:03 UTC