-
Notifications
You must be signed in to change notification settings - Fork 331
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
How response bodies get from a service worker to the main page is not very clear #330
Comments
|
Transfer means copying and then detaching on the side you copied from. |
That means a script author will lose the access to the buffer wrapped by the Uint8Array object passed to |
I'm not sure. Given how requests and responses work with streams today it kind of makes sense to me that if you want to retain a value you clone it first. But we do need to make it deterministic when the transfer happens. |
Another point: We (Chrome) serialize the buffers to a C++ byte array and create Uint8Array objects from the byte array in the page. That means buffer's boundary is not preserved (i.e., buffers may be merged / split). As an implementer I would like the spec to allow us doing it. |
@wanderview fyi |
I agree we need to spec types. Can we do something in webidl like
I don't understand this one. Just because the outer ReadableStream is locked does not prevent the inner source from continuing to provide data, right? If we're using a Transform like a pipe, then the readable and writable sides really need to be individually lockable. Locking the reader side should not block other code from locking/using the writable side. This should be achievable via the inner source object.
I guess we can do this, but its likely just going to be a spec thing. I doubt we will ever represent actual browser images, stylesheets, etc as ReadableStreams. We're just going to consume them in c++. The only place it will actually happen this way is in an outer fetch() call that returns a Response.body.
Yea, I think its totally up to the browser what they do with the buffers. I don't want the spec to require a one-to-one buffer correspondence between a service worker provided Response.body and the outer fetch()'s Response.body that triggered the service worker interception. |
I think that's fine. Once you have enqueued a buffer, the consumer is allowed to read it and modify it arbitrarily (including transfering and detaching it). In this case the consumer is the UA.
This is an important point. I think that fits easily into the framework I outlined above. We just need to be a bit careful how things are specced. Instead of directly reading and enqueuing chunks as objects, we need to add some wiggle room in that process. Read the chunk as a Uint8Array, detach it, and enqueue new Uint8Array objects that point to the same sequence of bytes in the same order.
I am not sure how this would work. I guess my instinct is to first formalize the semantics and then see if any of them are boilerplatey enough that they could be taken care of by a Web IDL type / by bindings generators.
If by "inner source" you mean "underlying source", that's under the control of the author, not the UA. What I mainly meant here was that we couldn't just keep doing what the spec currently does, and pretend there's a single ReadableStream object which gets transferred around.
Basically there are two options. We could create a parallel "conceptual stream" type, with all the appropriate operations (reading, enqueueing, etc.) and say that is what is in play most of the time. Then the Or we could keep doing what the current spec does, and use a The latter sounds better to me. |
Thank you. I would like to use a transform stream to explain that in the spec. Let me try: Let
Note that each Uint8Array object's boundary needs not to be preserved, but the concatenation of all written bytes to In Does that make sense? Am I using streams' words correctly? |
That all makes sense. Given that we still haven't finished defining writable and transform streams (or piping) work in very much detail, I'm not sure how that's going to translate in the spec. That is why I suggested just describing it in terms of reading from |
Thank you. I made a pull-request w3c/ServiceWorker#934 based on @domenic's original post. I added a note to say that UAs need not preserve buffer's boundary. Hopefully we will replace the description with a more implicit one (i.e., transform stream + pipeTo). |
The current description pretends that a ReadableStream can be passed from one realm to another, which is wrong. This change changes the description so that it creates a new ReadableStream and passes Uint8Array objects from the old ReadableStream to the new one. This is discussed at whatwg/fetch#330. This change fixes w3c#850 as well.
The current description pretends that a ReadableStream can be passed from one realm to another, which is wrong. This change changes the description so that it creates a new ReadableStream and passes Uint8Array objects from the old ReadableStream to the new one. This is discussed at whatwg/fetch#330. This change fixes w3c#850 as well.
Right now the spec says that the internal response has a ReadableStream object. Since the internal response is shared between the service worker and the page, the ReadableStream is implicitly shared.
This is not very good. For example it implies sharing arbitrary JavaScript objects, since you can enqueue arbitrary JavaScript objects in the readable stream. Right now Chrome ignores all objects except Uint8Arrays. It should instead error in some way, but exactly how is not clear, since there is no spec.
At first I thought this would be related to structured cloning of readable streams (whatwg/streams#276 and whatwg/streams#244) but that might not be true. Our plan for structured cloning was to lock the stream. But that will not work in this case, as we want the service worker code to be able to enqueue at the same time the main thread code is reading.
I guess what we need to do is specify how each
Response
object has aReadableStream
object. Then respondWith() roughly does the following:ReadableStream
Response
'sReadableStream
. For each chunk:ReadableStream
ReadableStream
.Apologies if we already have some of this and I missed it.
The text was updated successfully, but these errors were encountered: