Shutdown event sometimes does not trigger when reloading (watchfiles) #2392
Replies: 3 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.
-
Environment:
When running uvicorn with reloading, 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:
Save as
main.py
and runuvicorn --reload main:app
(also make sure uvicorn is using watchfiles).Then, in your code editor, save the file two times quickly (you can increase the
asyncio.sleep()
duration to make this easier). You should see that the shutdown event is not run when reloading the second time. For example, these are the logs I see when saving twice in quick succession:Server is shutting down
is not printed a second time. I believe this is because in Server._serve(), we eagerly return ifself.should_exit
is already set to True here. If I change this to the following:The shutdown event always runs when reloading and resources are cleaned up.
Happy to open a PR for the above if this is a welcome change. If not, is there another change we could make to fix this issue? This is important because I need to clean up resources in my shutdown event.
Another edge case is that any time two signals arrive in quick succession, if the second one is a SIGINT (so for example, save the above file and press Ctrl+C in your terminal immediately after), uvicorn interprets that as a force-exit and will not communicate the shutdown event. It should ideally check that both signals are SIGINTs (so a double Ctrl+C) to avoid falsely setting
force_exit
. Another observation in this example is that uvicorn will capture the SIGTERM from the reloader (essentially converting a SIGINT to a SIGTERM+SIGINT when re-raising the signals). Is that intended?This is part of a broader question of whether the shutdown event should run in the case of a force-exit. I understand if that's not desired, but there doesn't seem to be a good workaround to clean up resources in that case (e.g., in the case of using multiprocessing, this will lead to orphan processes).
Beta Was this translation helpful? Give feedback.
All reactions