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 option to automatically abort response stream if the data stopped arriving for longer than a specified time #180

Open
kornelski opened this issue Dec 14, 2015 · 14 comments
Labels
addition/proposal New features or enhancements topic: api

Comments

@kornelski
Copy link

I'd like to have an option to abort (internally by the browser, not via a JS API) requests that have stalled, i.e. close the TCP/IP connection if the time since the last bit data received exceeded a specified timeout.

This is different from a deadline (#179, #20), because it allows very slow, but steady, responses to stream forever.

fetch('/1MB.json', {timeout: 5000}).then(res => res.json);

This promise would succeed on a GPRS connection with a good signal that requires 4 minutes to download the file, but thanks to a good signal it delivers the file at a good consistent pace, so there's never a gap longer than 5 seconds between received chunks of the file.

This promise would fail on a fast 4G connection in 5 seconds after the user has lost signal, even if a portion of the file has already been downloaded, but due to lost signal the rest of the file stopped arriving.

Timeout-since-last-data-arrived is a timeout independent of file size and mostly indifferent to the network speed. This allows developers to use shorter timeouts than if they had to use a worst-case-scenario deadline for the whole response to arrive, so the application can react to failing network conditions quicker, and minimize time spent in a "stuck" state.

@annevk annevk added the addition/proposal New features or enhancements label Jan 7, 2016
@afilp

This comment has been minimized.

1 similar comment
@jpierson

This comment has been minimized.

@aronwoost

This comment has been minimized.

@rogeriochaves

This comment has been minimized.

1 similar comment
@okjungsoo

This comment has been minimized.

@annevk
Copy link
Member

annevk commented Feb 28, 2016

If you consider responding to this issue with +1, please subscribe instead and maybe read https://wiki.whatwg.org/wiki/FAQ#.2B1. Not sure why this is almost exclusively happening here, but this is not helping.

@wheresrhys
Copy link

I think the breakdown between this issue and #179 clarifies #20, but I think neither of them address the original aim of #20, which is to have an equivalent of xhr timeout.

I originally raised #20 with a far more naive understanding of the fetch & streaming APIs, but this is also the standpoint many developers will be coming to fetch from. 'If the content doesn't arrive in Nms, abort and show an error message' will still be a common/the commonest use case (perhaps not for developers strongly versed in SW, streams etc... but that isn't most developers)

With that in mind I'd prefer an API something like:

opts.timeout - timeout in miliseconds
opts.timeoutType - 'headers' (equivalent to #179), 'stream' (equivalent to this issue) or 'content' (which sets a timeout on .json() or .text())

'content' would have no effect if .blob() is called. 'stream' would probably still have an effect if .text() or .json() are called, but it could also make sense for it to not do. Both 'stream' and 'content' would reject if headers do not return in time. I'm not sure which I would favour as the default, but probably 'content' as then the behaviour is more friendly for developers moving to fetch from xhr

@wheresrhys
Copy link

Or what would make more sense, and fit with the extensible web ethos of low level APIs first, is accepting an object for timeout allowing numerous timeouts to be specified

e.g.

timeout: {
   firstByte: 700,
   headers: 1000,
   fullContent: 2000,
   interPackage: 50
}

with timeout: 2000 being an alias for timeout: {content: 2000}

@annevk
Copy link
Member

annevk commented Feb 29, 2016

@wheresrhys that would only fit with the extensible web efforts if browser network libraries had such an API. I very much doubt they do.

@as-aaron
Copy link

The lack of some way to set reasonable timeouts makes this API unusable for Cordova based mobile apps. Users expect their apps to respond in a reasonable time and we need to be able to control this.

Yes you can use settimeout and then ignore the request but leaving a no longer useful connection open in the background that may waste data is not acceptable for a mobile app where connectivity is potentially flaky, especially if you want to limit the number of connections to your API.

@adambene
Copy link

The lack of some way to set reasonable timeouts makes this API unusable for Cordova based mobile apps. Users expect their apps to respond in a reasonable time and we need to be able to control this.

Same here, but ReactNative.

@panuhorsmalahti
Copy link

To add to @apet-as's point, it's not acceptable to leave unused connections open in the browsers - most(?) browsers have a quite small limit on concurrent open connections, so it's important to be able to cancel a request and close the connection properly.

@JeremyGreen-TomTom
Copy link

For TCP, this could be implemented via the SO_RCVTIMEO and SO_SNDTIMEO socket system-call options (java calls the pair SO_TIMEOUT in its Socket API).

@JeremyGreen-TomTom
Copy link

Using AbortController and setTimeout isn't any use if e.g. you've got a chunk-encoded response where you don't know how long it's going to take before it's complete.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements topic: api
Development

No branches or pull requests