-
-
Notifications
You must be signed in to change notification settings - Fork 748
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
Further timeouts and resource limiting. #157
Comments
Hello, Apologies for chiming in on this, but my use case could really use this feature. I have a very large sql query that uses sqlalchemy (so it is not async, from the start). This is an internal "big data" app, so there is no pressure for super low latency per request. I'm streaming lines of json with a starlette However, the query takes about 90-120 seconds to get started actually producing results. Anyway, I just wanted to bump this. If you pointed me to the code where the timeout actually occurs, I might be interested in trying a PR, if you'd be interested (at least for the Thanks! |
I guess #995 is for |
For a timeout if a response is not returned within X seconds does simply |
@hoopes I could be mistaken but from my initial reading of the codebase, there's no hardcoded timeout for http requests. It's probably some other issue that's causing uvicorn to not return a response. |
@caleb15 ok! sorry for not following up strongly here, my work has taken me in other directions. my apologies for dirtying up a thread. |
So I implemented a timeout using a middleware in our django codebase: class TimeoutMiddleware:
"""
Times out a request after X seconds
"""
def __init__(self, app: ASGI3Application) -> None:
self.timeout = settings.HTTP_TIMEOUT
self.app = app
async def __call__(
self, scope: Scope, receive: ASGIReceiveCallable, send: ASGISendCallable
) -> None:
# TimeoutError? If this happens often you should either optimize
# the code or route the endpoint to the long pods, which
# have a higher timeout
try:
await asyncio.wait_for(self.app(scope, receive, send), self.timeout)
except asyncio.TimeoutError as e:
sentry_sdk.capture_exception(e)
await send(
{
'type': 'http.response.start',
'status': 504,
}
)
await send(
{
'type': 'http.response.body',
'body': b'504 Error - Your request took too long and was cancelled.',
}
) With initial testing this appeared to work fine. However, when the code got pushed to production a very large number of timeout errors started happening. Upon further testing I realized that the timeout includes the time requests spend waiting to be processed behind other requests. This unfairly penalizes requests that are stuck for a long time. For example, if a request waited for 5 seconds and took only 2 seconds to process with a timeout of 6 seconds, it would get cancelled because 5+2 > 6. I think I would need to know more about uvicorn to implement this properly. How does the "queuing" logic work? I'm in the dark as to how requests are distributed among threads and where they are queued up when a thread is busy. |
I'm not sure I understand what your question is about threads, as everything happens in the main thread and the event loop is scheduling the instructions on it. |
I think EDIT: Actually, the
Ref.: https://h11.readthedocs.io/en/latest/api.html#h11.Connection |
|
--limit-request-line-size (4096, See gunicorn)--limit-request-header-size (8190, See gunicorn)--limit-request-header-count (100, See gunicorn)@Kludex notes
--limit-request-header-count
. The header size limitation is enough.startup
andshutdown
lifespans?Important
The text was updated successfully, but these errors were encountered: