[whatwg/streams] Add a flag to determine wether a ReadableStream is disturbed or cancelled (#1025)

## Proposal

Implement flags to determine in a synchronous way wether the stream is disturbed and cancelled as boolean properties `ReadableStream#isDisturbed` and `ReadableStream#isCancelled`.

## Rationale

ReadableStream should have a flag which describes if the stream is disturbed or not. Without this flag it's just **impossible** to understand if the first chunk of the stream would be the first chunk of the data. That's why behaviors to check is stream has been read already is implemented in all major browsers ([Chromium](https://github.com/chromium/chromium/blob/40935da55702f890dc4fa0598db880995e965902/third_party/blink/renderer/core/fetch/response.cc#L301), [Safari](https://trac.webkit.org/browser/webkit/branches/safari-609.1.12-branch/Source/WebCore/Modules/fetch/FetchBody.cpp#L67), [Firefox](https://hg.mozilla.org/mozilla-central/file/tip/dom/fetch/Fetch.cpp#l1155)) and is using by FetchAPI (Response and Request constructors).

I know there is an opinion against it. But, as I've already showed, without such flags it's impossible to implement reliable solution. Current design creates asynchronous undefined state and doesn't allow to understand wether the stream is correct constructor argument or not and lead to unpredictable delayed race conditions. As I understand such a solution made due to assumption that stream can be non-exclusively owned and as a result cancelled in any time, what seems incorrect.

## Example

I'm implementing a server which works with Web StreamAP. It requires an ability to check, if the stream contains an acceptable body or not, to prevent throwing parsing errors on valid request and to detect race condition occurred in the process of request handling. Currently I solve this in a hacky way using lowlevel API from the Response object implementation, without this I will emit error each time someone else read the stream without being sure where in the code it has happened.

Solution with Response constructor:

```ts
function isStreamDisturbed(stream: ReadableStream): Boolean {
  try {   
      new Response(stream)
    
      return false
    }
    catch {
      return true
    }
}

const stream = new ReadableStream()
stream.cancel()

isStreamDisturbed(stream) // -> true
```

Of cause this solution is a hack and couldn't be decided as reliable.

-- 
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/1025

Received on Sunday, 15 December 2019 07:31:00 UTC