-
-
Notifications
You must be signed in to change notification settings - Fork 749
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
Fix shutdown event on Windows in reloader #1584
Fix shutdown event on Windows in reloader #1584
Conversation
For reference, what the description says is written here: https://docs.python.org/3/library/multiprocessing.html#multiprocessing.Process.terminate |
Without the reload flag, does it run the shutdown event? |
In my tests, It seems the shutdown event is set without the reload flag, since there is no |
Can we do something like https://stackoverflow.com/a/47314406/13087720 here? |
After digging into with open(wfd, 'wb', closefd=True) as to_child:
# start process
try:
hp, ht, pid, tid = _winapi.CreateProcess(
python_exe, cmd,
None, None, False, 0, env, None, None)
_winapi.CloseHandle(ht)
except:
_winapi.CloseHandle(rhandle)
raise While |
@StarHeartHunt If you have time, it would be cool to add a test for the changes, and fix the pipeline. 👀 🙏 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test is still needed for Windows (pytest.mark.skipif
should help), and I need some people with Windows to help me here. 👀
@Kludex i have windows! :) |
Ok... And this PR works there? 👀 |
Tried getting a subprocess in pytest but got an |
We actually already have a test for it, it's the one you've modified 😅 So... Someone can confirm this works? Someone from the team has a way to test this locally? @encode/maintainers |
EDIT: I meant all tests pass |
By "testing" I mean manually checking that it works on Windows. We have windows on our pipeline, so I know the tests are passing on Windows 👀 |
Works on my machine
from contextlib import asynccontextmanager
from typing import AsyncGenerator
from fastapi import FastAPI
from starlette.applications import Starlette
@asynccontextmanager
async def lifespan(app: Starlette) -> AsyncGenerator[None, None]:
print("START")
yield None
print("SHUTDOWN")
app = FastAPI(lifespan=lifespan) Install deps $ pip install fastapi
$ pip install git+https://github.com/StarHeartHunt/uvicorn@bug/fix-shutdown-event-on-windows-in-hot-reloader --force-reinstall Run $ uvicorn app:app --reload
INFO: Will watch for changes in these directories: ['C:\\Users\\aceus\\perso\\tmp']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [2108] using StatReload
INFO: Started server process [19776]
INFO: Waiting for application startup.
START
INFO: Application startup complete.
WARNING: StatReload detected changes in 'app.py'. Reloading...
INFO: Shutting down
INFO: Waiting for application shutdown.
SHUTDOWN
INFO: Application shutdown complete.
INFO: Finished server process [19776]
INFO: Started server process [8672]
INFO: Waiting for application startup.
START
INFO: Application startup complete.
INFO: Shutting down
INFO: Waiting for application shutdown.
SHUTDOWN
INFO: Application shutdown complete.
INFO: Finished server process [8672]
INFO: Stopping reloader process [2108] |
Hi, this pr works with our application and the log is here: nonebot/nonebot2#1654 (comment) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @StarHeartHunt 🙏
Do we need to do the same for the |
I'm not sure if this PR will meet the issues in #684. I can't test because I'm using a MacBook right now, it would be nice if someone could try it. |
Using the repro by @abersheeran in it, I tried, and it works well. ➜ uvicorn app:app --reload
INFO: Will watch for changes in these directories: ['C:\\Users\\ava\\Projects\\uvicorn-test']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [2704] using StatReload
INFO: Started server process [12708]
INFO: Waiting for application startup.
START
ERROR: Traceback (most recent call last):
File "C:\Users\ava\AppData\Local\Programs\Python\Python312\Lib\site-packages\starlette\routing.py", line 677, in lifespan
async with self.lifespan_context(app) as maybe_state:
File "C:\Users\ava\AppData\Local\Programs\Python\Python312\Lib\contextlib.py", line 204, in __aenter__
return await anext(self.gen)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\ava\Projects\uvicorn-test\app.py", line 10, in lifespan
afhajdhfa
NameError: name 'afhajdhfa' is not defined
ERROR: Application startup failed. Exiting.
WARNING: StatReload detected changes in 'app.py'. Reloading...
INFO: Started server process [11988]
INFO: Waiting for application startup.
START
INFO: Application startup complete. |
Thanks. |
Once rebased, we can merge it. 🙏 Once again, thanks @abersheeran 🙏 |
commit f01b630 Author: StarHeartHunt <starheart233@gmail.com> Date: Thu Apr 13 18:28:13 2023 +0800 fix: indent commit 353c0af Author: StarHeart <starheart233@gmail.com> Date: Tue Mar 28 19:14:34 2023 +0800 Update uvicorn/supervisors/basereload.py Co-authored-by: Marcelo Trylesinski <marcelotryle@gmail.com> commit 1cfd29c Author: StarHeartHunt <starheart233@gmail.com> Date: Fri Oct 28 19:23:22 2022 +0800 fix: fix should_exit trigger commit 1601440 Author: StarHeartHunt <starheart233@gmail.com> Date: Sat Oct 22 20:10:25 2022 +0800 test: update test commit 1e48e1e Merge: 2300113 b06cc63 Author: StarHeart <starheart233@gmail.com> Date: Sat Oct 22 19:59:16 2022 +0800 Merge branch 'master' into bug/fix-shutdown-event-on-windows-in-hot-reloader commit 2300113 Author: StarHeartHunt <starheart233@gmail.com> Date: Sat Oct 22 19:57:38 2022 +0800 fix: resort imports commit 21e563d Author: StarHeartHunt <starheart233@gmail.com> Date: Sat Oct 22 19:55:40 2022 +0800 test: update test script commit 720a28d Author: StarHeartHunt <starheart233@gmail.com> Date: Sat Oct 22 19:20:31 2022 +0800 fix: propagate Ctrl+C event to child process on Windows commit 338c25c Author: StarHeartHunt <starheart233@gmail.com> Date: Sat Oct 22 17:58:00 2022 +0800 fix: try to fix pipeline commit 293593a Author: StarHeart <starheart233@gmail.com> Date: Fri Jul 29 17:51:41 2022 +0800 Fix shutdown event on Windows in hot reloader test: add missing pragma spec
Did this caused #1977 ? |
It seems couldn't be reproduced on my Windows 10 laptop. I think it's not relevant to #1909 or #1584 Use case and test script, by randomly adding and removing lines to trigger reload and see from contextlib import asynccontextmanager
from typing import Union
from fastapi import FastAPI
@asynccontextmanager
async def lifespan(app: FastAPI):
print("startup")
yield
print("shutdown")
app = FastAPI(lifespan=lifespan)
@app.get("/")
def read_root():
return {"Hello": "World"}
@app.get("/items/{item_id}")
def read_item(item_id: int, q: Union[str, None] = None):
return {"item_id": item_id, "q": q} Start uvicorn by the following command uvicorn main:app --reload And the environment
|
On Windows, using
Process.terminate()
will immediately kill the child process so that the asgi event shutdown cannot be triggered in reloader. This PR is going to implement a graceful exit of child process.