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

Disconnect event is not propogated to the middleware while a request is processing #286

Open
speksen-kb01 opened this issue May 3, 2024 · 3 comments

Comments

@speksen-kb01
Copy link

Hello,

We were working on an HttpDisconnectMiddleware, which would cancel the ongoing tasks when user cancels the requests.
We were using this same middleware with other servers like uvicorn and hypercorn, which would trigger the exception upon cancellation, but in the case of granian, it seems like the disconnect event is queued and not sent to the middleware, and only sent to it after the task finishes.

I've created a repo for showcasing the effect,
https://github.com/speksen-kb01/fastapi-disconnect-example

Is there a reason why we couldn't get the event while a request is being processed? If so, what do you think it is related to and is it fixable by changing the middleware to some extent?

@speksen-kb01 speksen-kb01 changed the title Disconnect event is not propogated to the middleware while a request are processing Disconnect event is not propogated to the middleware while a request is processing May 3, 2024
@gi0baro
Copy link
Member

gi0baro commented May 6, 2024

@speksen-kb01 yes, at the moment the network I/O in Granian doesn't allow to be notified when connection gets closed prematurely by clients. In fact, network I/O in Granian today is eager, meaning checks over connection state are run only when actually reading and writing: if you change the code to try writing back empty contents during that 10 seconds, you should be able to get the exception you're looking for.

This might be changed in the future – if a valid reason to change the current behaviour exists – but it really depends on the lower library capabilities.
I have a question indeed: can you provide a use-case for this? 'cause looking at the middleware code you provided, there's nothing special the app might benefit from, a part getting an exception – if I got it correctly?

@aeb-dev
Copy link

aeb-dev commented May 6, 2024

Imagine that the endpoint is something that consumes too much resource and it can be called multiple times by a single client in parallel. In order not to waste resource we want to cancel as soon as we receive a disconnect event

@speksen-kb01
Copy link
Author

@speksen-kb01 yes, at the moment the network I/O in Granian doesn't allow to be notified when connection gets closed prematurely by clients. In fact, network I/O in Granian today is eager, meaning checks over connection state are run only when actually reading and writing: if you change the code to try writing back empty contents during that 10 seconds, you should be able to get the exception you're looking for.

This might be changed in the future – if a valid reason to change the current behaviour exists – but it really depends on the lower library capabilities. I have a question indeed: can you provide a use-case for this? 'cause looking at the middleware code you provided, there's nothing special the app might benefit from, a part getting an exception – if I got it correctly?

I see, thanks for the explanation. For the use case part, Imagine a "request chain" that depend on each other to finish, and it takes some time, for each to finish it's task.
user -> service1 -> service2 -> service3
Let's assume user just cancelled the request, after each service called each other. Using the middleware, service1 would get an exception, basically cancelling whatever it's doing. Since service1 abruptly disconnects, service2 also would get an exception and so on along the chain, cancelling each task. Without the middleware, if the user disconnects, the chain continues it's work for naught, making db connections etc. Basically continuing hogging resources.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants