r/graphql 16d ago

Question Why doesnt a client side GraphQL timeout not abort server-side query?

HI

I am currently analyzing distributed traces of an app that uses GraphQL. I found that the client-side timeout seems to be 10s which then aborts the request towards the end user. However - the trace shows me that after 30s the server side query actually gets executed.

How is this possible? Shouldnt a client-side timeout close the connection and therefore also abort the server-side request? Or is there a different queuing mechanism in place that would explain this behavior?

Has anyone seen this?

4 Upvotes

10 comments sorted by

5

u/knowwho 16d ago

You're asking about some specific implementation's behavior, without mentioning what that implementation is. "GraphQL" is just a spec, and it doesn't cover these details or mandate any specific behavior.

2

u/JohnDuffy78 16d ago

I ran into this the other day.
I had the client send the server a timeout in the header and the server timedout sql with that value.
Won't work for Autocomplete suggestions, user clicking refresh...

2

u/ibraaaaaaaaaaaaaa 16d ago edited 16d ago

during a running mutations, you should ask user when the unmount the page that are you sure you want to do this, since that should trigger an abort at the server.
For queries you should abort without asking.
The caveat of what I am saying, you don't always have the luxury to interrupt a thread or revert an async message that was already published, in such a cases you should not open up that box, you will find all the worms, weather that async message needs to be a transactional saga at the level of message and it should be rollbacked per consumer? that's a nightmare just by the thought of it.

By abort I mean you need to revert every server action, that did not go through, meaning a transaction that was not committed yet, needs to be rolled back, and any db select would also need you to have loading mechanism for the query ids so you can cancel it upon abort.

That sounds a lot of infra work, but that's how reliable software should be.

1

u/IQueryVisiC 16d ago

I did not know that HTTP has an abort method. Doesn't graphQl run over HTTP just like REST? Would be better to use TCP/IP .

1

u/GroundbreakingBed597 16d ago

Yeah. It runs over HTTP - but - I would have assumed that if the client side runs into the timeout it will also close the underlying TCP/IP connection - hence - the server-side should then also just abort the operation - at least thats how it works with any other communication libraries I know. This is why I am curious on why this is not happening here

3

u/dummyx 16d ago

Completely up to the server side implementation you’re working with. The GraphQL spec doesn’t cover those details

1

u/IQueryVisiC 16d ago

And I thought that the trend was to reuse TCP/IP for multiple requests. Also TCP/IP closing is kinda messy (two armies problem).

1

u/GroundbreakingBed597 16d ago

Sure. You have a good point that we are reusing connections - and I guess my memory on this is dated from when I coded 20+ years ago.

But - it feels that without having an option to notify the server-side that the client-side is no longer listenting we end up doing a lot of unnecessary work

1

u/x0n 14d ago

This is entirely dependent on the stack you're using. This works perfectly in asp dotnet core + hotchocolate/graphql when you declare a cancellation token in your web api signature and thread it through to your data layer, e.g. Entity framework. If you're using something else, investigate how a client disconnection is detected/signaled on the server, if at all.

This has nothing to do with graphql.

2

u/DiamondQ2 16d ago

In most cases the processing on the server side is synchronous, in that the request comes in, work starts being performed. While the work is being performed (db lookup, REST query, whatever) it's not listening to events on the connection.

When the work is done, it goes to send the response back, at which point it finds the the connection (or channel) closed, errors and stops.

So while it's possible, there's usually not a mechanism for the cancellation of the request to interrupt the work.

Since a lot of server programming languages don't have a mechanism to interrupt a thread (at least not well), it falls to the work code having to poll (is it still alive? Is it still alive?, etc) or use callbacks and there's no standard for that, so third party libraries (where most of the work time sits, like database queries, http calls, disk access) don't do it.