Re: [whatwg/streams] Allow stream reader cancel() method to return bytes from queue instead of discarding them. (#1147)

> @domenic, can you reopen this issue? If there's action to take here then it should be done at the Streams API level.
> 
> While it might be nice syntactically to have `cancel()` return any bytes left in the queue I think this can be polyfilled with,
> 
> ```js
> const finalReadPromise = reader.read();
> await reader.cancel();
> const finalRead = await finalReadPromise;
> ```
> 
> If there was any data left in the queue then it will be in `finalRead.value`. Otherwise, if the read was blocked waiting for more data then `finalReadvalue` will be `undefined`. The key insight here being that you can do a "non-blocking" read to see if there are queued bytes by not awaiting on the `Promise` it returns. Once you call `cancel()` then that `Promise` is guaranteed to have resolved one way or another.

So we agree that this does not preserve any data in buffer?

Second, "reader.cancel()" is called to cancel reader NOT the stream itself. The whole stream has its own readable.cancel() to discard buffers.

This simple change - the last outcome of the canceled read operation are bytes read so far and done=true, will open more possibilities. E.g writing simple, async sequential like code even with well known timed-out read.

Otherwise, having the all modern JS , async, await, promises, stream apis, to send and read few bytes you need to implement state machine or own FIFO buffer.

I literaly used it this way in a loop.
if( FIFO.available()) return FIFO.pop();
data = await reader.read();
FIFO.push( data.value) 

but why design API to loose data without any reason. Rigth after cancel(), opened port starts to collect the next bytes received. 

As spec says https://wicg.github.io/serial/#dom-serialport-readable
`Some other ways of encoding message ...  to wait a defined length of time before transmitting the next message.`
It's quite common to wait some time for an answer.

The read loop pattern is just callback disquised as promise based api.
`port.onavailable( data =>{ do_something( data)}) `
will do the same without the hassle of the whole infrastructure/locking.

But to do something non trivial this way you need to store and maintain at lest reader/writer and global state or FIFO. 
So we need something like (or built with generator)

```
do_something( data){
 if( global_state = credentials_prompt)
  global_state = credentials_reply;
  send_credentials();
 }
if( global_state = credentials_reply){
  If accepted( data) {
    global_state=credentials_accepted;
  }else{
    global_state=access_denied;
    reader.cancel();
    reader.releaseLock();
}
}
if( global_acceptes = credentials_reply)
...
```











-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/streams/issues/1147#issuecomment-883281425

Received on Tuesday, 20 July 2021 10:25:53 UTC