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

Feature idea: Abort pending requests #1541

Closed
lucasfeliciano opened this issue Apr 4, 2017 · 21 comments
Closed

Feature idea: Abort pending requests #1541

lucasfeliciano opened this issue Apr 4, 2017 · 21 comments

Comments

@lucasfeliciano
Copy link

lucasfeliciano commented Apr 4, 2017

I saw that in the middleware the req object has a request object with operationName.

{query: Object, variables: Object, operationName: "Search"}

So I'm figuring out a way to cancel previous request with the same operationName.

Motivation

The motivation behind is to use this feature on search's autocomplete/suggestions.

So when a new query is made we cancel the last request if it is not completed yet, so make it easy to treat the asynchronism in the frontend.

@helfer
Copy link
Contributor

helfer commented Apr 4, 2017

@lucasfeliciano in a sense this already happens. If the same component makes queries in quick succession, server responses from previous requests are ignored when there's a more recent request already under way. What more would you need?

@ariesshrimp
Copy link

I was having this conversation at work today. What about these two cases:

  1. Terminating a file upload.
  2. Sparing the clients data usage. Apollo throws out the old result, but the client is still forced to load the result, right?

@helfer
Copy link
Contributor

helfer commented May 2, 2017

@joefraley there's no way for us to cancel the request once it's been sent to the server. That would require specific logic on the server that we have no control over. Currently Apollo Client will receive the result, but it will throw it away if it's not the most recent request made by an active observable query.

I'm closing this since it seems the feature requested is already implemented 🙂

@helfer helfer closed this as completed May 2, 2017
@ariesshrimp
Copy link

ariesshrimp commented May 3, 2017

@helfer I understand that users would need to implement their own server side logic to handle the cancellation. But that's only possible if the Apollo client fires a cancellation.

With no client cancellation, there is no way to handle the desired case. With client cancellation, people that need it can account for it on the server, and people that don't need it will not notice any change from the present day behavior.

I'm assuming that the client can't cancel because it's using the native fetch API today, so I guess this proposal is partly to use a different request method that permits cancellation (like axios or the native XHR).

@lucasfeliciano
Copy link
Author

@helfer I have to agree with @joefraley

Support this on client side is kinda a must have feature for big and high quality applications

@ariesshrimp
Copy link

ariesshrimp commented May 3, 2017

@helfer @lucasfeliciano it's possible to set up your own custom network interface that does support cancellation if you're using apollo-react, but it requires rebuilding the apollo-client network layer and extending its API. I don't know if other Apollo libraries support that idea or not.

My product can't support GraphQL without cancellation.

Another possibility is to set your cancellation endpoints aside from gql. So keep hitting a one of rest point for search, but gql your other stuff. That only works if a limited subset of your app needs cancellation though.

@lucasfeliciano
Copy link
Author

lucasfeliciano commented May 3, 2017

Indeed, I think we should have this implemented in apollo client it self.

Passing a boolean in the options object of the graphql() method or in the network interface to enable this in a specific query or globally, the tricky part is that we need cancel the request only for that type of query.

I need to think about this, I might play with the request object since the same has the operationName:

{query: Object, variables: Object, operationName: "Search"}

Which is the query name

@stalniy
Copy link

stalniy commented Sep 4, 2017

It looks like it's not hard to implement custom network interface which extends HttpFetchNetworkInterface And override fetchFromRemoteEndpoint method, use inside XMLHttpRequest and do custom logic with request abort

@felixfbecker
Copy link

felixfbecker commented Dec 20, 2017

The latest version of the fetch API is cancellable (implemented in Firefox and Edge, easy to polyfill): https://developer.mozilla.org/en-US/docs/Web/API/AbortController

Any plans to implement that?

@larube
Copy link

larube commented Jan 5, 2018

In my project, I also need that feature. I launch a query but i would be able to cancel it depending on user action .... Do you think that this feature will be implemented ?

@klis87
Copy link

klis87 commented Jan 5, 2018

I think this feature is really needed. For example, lets say some private data is being fetched and user clicks logout. With a slow network, we could have a race condition, when private data would arrive after user logged out. Aborting a pending request in the case like this would prevent such a disaster.

@Timopheym
Copy link

Heeey! @helfer Is there news about it? Could it be done?

@pennyandsean
Copy link
Contributor

Running into this problem now in relation to data coming back to unmounted components. Looks like Dan's in favour of cancellation for api libraries.

@bgentry
Copy link
Contributor

bgentry commented Mar 4, 2018

I think this issue should at the very least be reopened now that it is possible to cancel fetches with AbortController. As Dan pointed out in the above link, there are many classes of problems which are best solved by canceling the ongoing request.

And since most browsers and modern CDNs have HTTP/2 support, those requests can often be canceled without ending the connection and without the server sending any unwanted data.

@abhandaru
Copy link

Please reopen this issue.

Request cancellation from the client offers many benefits including but not limited to:

  • Conserving data usage
  • Implementing timeouts retry policies
  • Resolving race conditions and winners
  • Allowing servers to appropriately conserve resources and terminate requests

There is ample precedent for adding cancellation to asynchronous APIs.

@stalniy
Copy link

stalniy commented Mar 13, 2018

Guys I believe this was implemented as part of Apollo link. Check the source code : https://github.com/apollographql/apollo-link/blob/master/packages/apollo-link-http/src/httpLink.ts

@klis87
Copy link

klis87 commented May 14, 2018

@stalniy this would probably work if observable responsible for a request is cancelled (abort would be triggered then), but does it ever happen actually? lets say we have a query pending and before it finished, a component just unmounted - I guess this query will finish executing and abort will never be triggered

@nagman
Copy link

nagman commented May 28, 2018

@stalniy I'm using the unsubscribe() method of the Observer generated by apollo, and it doesn't kill the query at all.
The callback isn't triggered because I unsubscribed it, but apollo is still polling for the server's answer.

I'm using it inside of an autocomplete component, and I unsubscribe the previous subscription each time I type a key.
But instead of killing previous fetches, they pile up and the more I type, the longer it takes to display the results (because all the queries are executed and the final result only displays at the end).

However, when I copy/paste an entire word, as it triggers only one request, it's blazing fast.

So... there's still a need for this feature. The unsubscribe() method should abort the fetch query.

@stefanholzapfel
Copy link

Same problem here. I have an autocomplete where every keystroke changes/re-fires the query. At the moment I unsubscribe in a delayed timeout function to avoid that issue, which is VERY ugly and unreliable.

Is there any property on the subscription which indicates wether the subscription is already in an "unsubscribeable" state?

Thanks!

@klis87
Copy link

klis87 commented Aug 3, 2018

Any news re potential introducing of requests aborts? For REST APIS, I am heavy user of Redux-Saga, and I really appreciate control which it gives me - saga aborts, effects like takeLastest, takeEvery, all, race, which give awesome control which can prevents subtle race condition bugs, especially on mobile devices.

I really like Apollo and I think that it is really the future of the way apps should be written, but because it is declarative, we dont have much networking control, Apollo does all the lifting for us, but this has a cost, and I believe that introducing aborts, takeLastest, takeEvery, all, race counterparts would be a missing puzzle to the equation.

@hwillson
Copy link
Member

hwillson commented Aug 8, 2018

To help provide a more clear separation between feature requests / discussions and bugs, and to help clean up the feature request / discussion backlog, Apollo Client feature requests / discussions are now being managed under the https://github.com/apollographql/apollo-feature-requests repository.

Migrated to: https://github.com/apollographql/apollo-feature-requests/issues/40

@apollographql apollographql locked and limited conversation to collaborators Aug 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests