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 reject the fetch promise automatically after a certain time elapsed (with no API for arbitrary aborts) #179

Open
kornelski opened this Issue Dec 14, 2015 · 9 comments

Comments

@kornelski

kornelski commented Dec 14, 2015

I'd like an option to have a deadline for the server to respond, so that if the response doesn't arrive within a specified number of seconds, the fetch promise is rejected and internally (i.e. without any sort of abort/cancellation API exposed to JS) the request is aborted by the browser on the TCP/IP level, so that bandwidth is not wasted in case the response does come later.

fetch('/slow', {deadline: 5000})
  .then(called_if_response_is_quick, called_if_response_is_too_slow);

It'd be less wasteful equivalent of:

const oldfetch = fetch;
fetch = function(input, opts) {
    return new Promise((resolve, reject) => {
        setTimeout(reject, opts.deadline);
        oldfetch(input, opts).then(resolve, reject);
    });
}

I wouldn't mind if the deadline was automagically propagated to response.json(), so that promise would be rejected too after the deadline.

Use-cases:

  • Overloaded web servers. Servers may accept connections quickly (e.g. by a reverse proxy or incoming-connection worker thread) even if they don't have "back-end" capacity to process the request, so requests are getting queued and responses won't be generated in a timely fashion.
  • Mobile connections with a very weak signal. Tethering via WiFi to a mobile device with no or weak signal.
    In such cases it seems that the browser is unaware that it has an unusable network connection, makes a request and never gives up waiting for a response (perhaps the request was successfully sent or at least was buffered somewhere along the way).

In such cases adding a deadline helps identify unusable network or servers quicker (the developer knows how fast the server is supposed to respond) and allows the application react to the situation rather than getting stuck forever (or for as long as very conservative deadlines are built into the browser or networking stack) or worse, having open and unusable connections exhaust browser's limit of open connections.

@aronwoost

This comment has been minimized.

Show comment
Hide comment
@aronwoost

aronwoost commented Jan 28, 2016

👍

@joshmangum

This comment has been minimized.

Show comment
Hide comment
@joshmangum

joshmangum commented Jan 29, 2016

+1

@rogeriochaves

This comment has been minimized.

Show comment
Hide comment
@rogeriochaves

rogeriochaves commented Feb 2, 2016

+1

@Mouvedia

This comment has been minimized.

Show comment
Hide comment
@Mouvedia

Mouvedia Apr 28, 2016

FYI this corresponds to the behaviour of XHR timeout. Which is what #20 is requesting.

Mouvedia commented Apr 28, 2016

FYI this corresponds to the behaviour of XHR timeout. Which is what #20 is requesting.

@buraktamturk

This comment has been minimized.

Show comment
Hide comment
@buraktamturk

buraktamturk May 7, 2016

Something like this just better than just specifying integer for timeout parameter. Manually cancelling the request is a thing.

#20 (comment)

var cancelpromise1 = new Promise(function(resolve, reject) {
     setTimeout(resolve, 1000);
});

var cancelpromise2 = /* a promise that will be resolved when user clicks cancel */;

var lastpromise = Promise.race([cancelpromise1, cancelpromise2]);

fetch(..., { timeout: lastpromise })
   ...

buraktamturk commented May 7, 2016

Something like this just better than just specifying integer for timeout parameter. Manually cancelling the request is a thing.

#20 (comment)

var cancelpromise1 = new Promise(function(resolve, reject) {
     setTimeout(resolve, 1000);
});

var cancelpromise2 = /* a promise that will be resolved when user clicks cancel */;

var lastpromise = Promise.race([cancelpromise1, cancelpromise2]);

fetch(..., { timeout: lastpromise })
   ...
@danostrowski

This comment has been minimized.

Show comment
Hide comment
@danostrowski

danostrowski Jul 20, 2016

+1, yes please.

danostrowski commented Jul 20, 2016

+1, yes please.

@isijara

This comment has been minimized.

Show comment
Hide comment
@isijara

isijara Aug 16, 2016

This would be really helpful

isijara commented Aug 16, 2016

This would be really helpful

@CamiloTerevinto

This comment has been minimized.

Show comment
Hide comment
@CamiloTerevinto

CamiloTerevinto Aug 20, 2017

It's now been over an year since the last comment, is there any progress on this?

CamiloTerevinto commented Aug 20, 2017

It's now been over an year since the last comment, is there any progress on this?

@jakearchibald

This comment has been minimized.

Show comment
Hide comment
@jakearchibald
Collaborator

jakearchibald commented Aug 21, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment