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

Add a flag to determine wether a ReadableStream is disturbed or cancelled #1025

Open
rumkin opened this issue Dec 15, 2019 · 6 comments
Open

Add a flag to determine wether a ReadableStream is disturbed or cancelled #1025

rumkin opened this issue Dec 15, 2019 · 6 comments

Comments

@rumkin
Copy link

@rumkin rumkin commented Dec 15, 2019

Proposal

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

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, Safari, Firefox) 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:

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.

@ricea

This comment has been minimized.

Copy link
Collaborator

@ricea ricea commented Dec 16, 2019

I am leaning towards adding isDisturbed (maybe just as disturbed?) but not isCanceled. We don't even track internally whether the stream was canceled. From the point of view of the consumer of the stream, it doesn't make a difference whether the stream was canceled or simply read until close.

@rumkin

This comment has been minimized.

Copy link
Author

@rumkin rumkin commented Dec 16, 2019

@ricea Replaced with disturbed and closed.

@yutakahirano

This comment has been minimized.

Copy link
Member

@yutakahirano yutakahirano commented Dec 18, 2019

disturbed is designed for Response.bodyUsed and I'm not sure if we should advertise its use widely. Personally I'm not a fan of the concept...

@rumkin

This comment has been minimized.

Copy link
Author

@rumkin rumkin commented Dec 20, 2019

@yutakahirano It's not only used for Response.bodyUsed it's mainly used to understand if response body is valid at all. This is why Response's constructor fails and not just set bodyUsed in true when the stream has been already disturbed. Without this restriction such things like ServiceWorker's cache wouldn't work correctly.

@yutakahirano

This comment has been minimized.

Copy link
Member

@yutakahirano yutakahirano commented Jan 7, 2020

disturbed represents whether the stream has ever been read. Validity is (or, at least, can be) a different concept I think.

@rumkin

This comment has been minimized.

Copy link
Author

@rumkin rumkin commented Jan 7, 2020

But in the concept of Request/Response, if the stream is disturbed, then it's not a valid body. So here "disturbed" and "valid" are synonyms.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
3 participants
You can’t perform that action at this time.