Shutdown event sometimes does not trigger when reloading (watchfiles) #2392
-
|
Environment: Per ASGI spec, is it expected that if a server sends a Specifically, the shutdown lifespan event will not run if there are multiple reloads in quick succession (for example if you save a file twice when using WatchFiles). I haven't observed this behavior with StatReload. Below is a minimal reproducible example: import asyncio
async def app(scope, receive, send):
if scope["type"] == "lifespan":
while True:
message = await receive()
if message["type"] == "lifespan.startup":
print("Server is starting")
await asyncio.sleep(2)
await send({"type": "lifespan.startup.complete"})
print("lifespan.startup.complete")
elif message["type"] == "lifespan.shutdown":
print("Server shutting down")
await asyncio.sleep(2)
await send({"type": "lifespan.shutdown.complete"})
print("lifespan.shutdown.complete")
elif scope["type"] == "http":
await send({"type": "http.response.start", "status": 200, "headers": [[b"content-type", b"text/plain"]]})
await send({"type": "http.response.body", "body": b"Hello, World!"})Save as
await self.startup(sockets=sockets)
if self.should_exit:
await self.shutdown(sockets=sockets) # Added
return
await self.main_loop()
await self.shutdown(sockets=sockets)The shutdown event always runs when reloading and resources are cleaned up. Another case is if you press ctrl-C twice in succession, that sets force_exit to true here, and we skip the shutdown event here. I understand if that is expected behavior but that can lead to resource leakage if people rely on the shutdown event to clean up resources, as is suggested by FastAPI in their docs. |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments
-
|
If anyone else is running into these issues, I have a fork here with the changes, adding |
Beta Was this translation helpful? Give feedback.
-
|
I am really interested in a solution to this. The current implementation seems like it did not consider the shutdown event being used to clean up resources. Is there a way the uvicorn recommends cleaning up resources prior to shutdown instead? |
Beta Was this translation helpful? Give feedback.
-
|
Also, a custom signal handler will not work because uvicorn overrides them before re-raising any signals: https://github.com/encode/uvicorn/blob/0.32.0/uvicorn/server.py#L327. Maybe this block of code should only reset the signal handlers if they are |
Beta Was this translation helpful? Give feedback.
-
|
I'm running into this as well, could someone take a look? |
Beta Was this translation helpful? Give feedback.
-
|
This would be great to have |
Beta Was this translation helpful? Give feedback.
-
|
I've merged a fix. It will be available in 0.41.0. |
Beta Was this translation helpful? Give feedback.
I've merged a fix. It will be available in 0.41.0.