-
Notifications
You must be signed in to change notification settings - Fork 311
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
Cancelling HTTP fetch #592
Comments
There's a concept of https://fetch.spec.whatwg.org/#concept-fetch-terminate which results in a network error of sorts. However, we haven't really detailed what UI actions can trigger such a thing and for which fetches. |
self.addEventListener('fetch', function(event) {
event.respondWith(
fetch('/whatever.json').then(function(response) {
return response.json();
}).then(function(data) {
return fetch(data.url);
})
);
}); We may not have a request to cancel when the user hits the stop button. As far as I know, we can only tie a response to a destination window once the promise passed to If the user hits X (or even closes the tab) while How does this sound? If the request is cancelled from the browser's point of view:
|
In Gecko, we have a loadgroup that knows about network requests. When a document goes away, the loadgroup terminates the relevant requests. So the fetch() will fail with an AbortError when called from documents. I'll let @wanderview comment if the same thing will work on workers now that he implemented loadgroups for them. Ben, when a SW is created for handling a document's request, will it (or can we make it) acquire that document's loadgroup? |
We definitely don't do that today. The SW has its own load group. Anything is possible, but it will be tricky. |
Maybe this should be merged into whatwg/fetch#20? |
I think this is https://www.w3.org/Bugs/Public/show_bug.cgi?id=23878 because it's about UI and not API. |
Ah, I see. Yeah, how to deal with such user actions should be discussed at the bug. Regarding how to inform not yet fulfilled fetch() of cancellation (Jake's comment #592 (comment)), once we have a canceller or cancellable promise (whatwg/streams#297 (comment) @domenic), it sounds like we should pass the canceller to |
Or more generally, it might be named
It seems it's not appropriate to include the controller receiver to |
Coming back to this a few days after the discussion in whatwg/streams#297 (comment) the key question is whether we want to require: (a) two separate cancellation mechanisms, one for before headers arrive and one after; or (b) a single cancellation mechanism that works for both. Any promise-cancellation--based approach seems to lean toward (a). You use promise cancellation for before headers arrive. After headers arrive, the promise is already settled, and you can't do anything to affect it. So after headers arrive you use stream cancellation. Approaches like @tyoshino's controller, or maybe an approach like |
(I thought we were discussing this particular API problem in #625 but I'm happy to move it here.) @tyoshino we could create So that leaves us with either a promise subclass or controller of sorts. Given the promise discussions on es-discuss it seems like we want a controller. And as far as @domenic's question goes I think it should be a mechanism that cancels the promise and the stream. The action is terminating network activity. The only worry I have is that the code gets a little awkward:
Also, if we go down this route I think the controller object should also expose state whether it is in use or not. And |
Yeah, I think a controller type thing will work well. We can later explain it in terms of promise cancellation + stream cancellation. A promise subclass would be confusing since
This is pretty reasonable. Not sure whether I like it more or less than @tyoshino's equivalent: resp = fetch(url, { control(controller) {
goElsewhereButton.addEventListener("click", () => controller.abort());
} }); |
Yeah, I guess my suggestion only makes sense if we want it to be reusable or usable for several fetches at once (probably makes little sense if we add more features, such as |
In whatwg/streams#297 (comment) we were thinking it would error the stream, since it simulates the browser terminating the connection, and can happen even if someone else has an exclusive reader (which normally prevents cancellation). That doesn't necessarily mean that the promise should reject. But it would be a bit more consistent that way. Hmm. |
I'm not sure how the controller approach works with promise/stream combinators. Any ideas? It seems like it would be an awkward additional set of arguments you have to pass in so it can synthesize a new combined controller, or else a separate controller-centric copy of each combinator. |
I have one more proposal for canceling FetchObject = {
// promise-like
then: function() {},
catch: function() {},
// cancel() method not related to promise at all
cancel: function() {}
};
In general, usage would look like this: var reqSomething = fetch('...');
var asyncDoSomethig = ...;
var onceDone = Promise.all([
reqSomething.then(function handleStream() { ... });,
asyncRenderSomething
]);
onceDone.then(function(args) {
// apply some stuff
});
onEscPressed(function() {
reqSomething.cancel();
}); So here Few other things: var reqSomething = fetch('...').reqSomething.then(function handleStream() { ... });
reqSomething.cancel(); So once someone needed to cancel fetch, then they may store origin This was seems not ideal, but other ways are not better. Thanks. |
edit: my cancel-ability concern has been solved, nothing to see here |
@WebReflection the comment you're quoting of mine is months old & you're taking it out of context. The browser will be able to cancel streams when the user hits x, the problem with that particular example is that the initial request does not go to the browser, it stays within the ServiceWorker. Fetches will become cancellable. Its underlying stream is already exposed in Canary and is cancellable. |
Then my apologies, I've got mislead by a recent tweet that was pointing to this discussion and since it's still open and there's no reference on "how to cancel" in the mentioned WHATWG page I thought it was still in the middle of its resolution. |
Closing this in favor of whatwg/fetch#27 |
When the user clicks the stop button while the page is loading a large file (example: a movie file) via the ServiceWorker, the ServiceWoer should stop the HTTP fetching to reduce the resource usage.
Is this behavior specified in the Fetch spec or the ServiceWorker spec?
The text was updated successfully, but these errors were encountered: