Uvicorn with reload hangs when using a ProcessPoolExecutor
See original GitHub issueChecklist
- The bug is reproducible against the latest release and/or
master
. - There are no similar issues or pull requests to fix it yet.
Describe the bug
When at last 1 task is submitted to a ProcessPoolExecutor
uvicorn fails to reload when a file change has been detected. It detects the file change and the server is shutdown but it doesn’t start again. As long as no tasks are submitted uvicorn is able to reload properly.
To reproduce
"""ProcessPoolExecutor Example.
Run
---
uvicorn main:app --reload
Versions
--------
fastapi~=0.63.0
uvicorn[standard]~=0.13.3
"""
from concurrent.futures import ProcessPoolExecutor
from typing import Any, Dict
from fastapi import FastAPI
app = FastAPI(title="Example API")
POOL = ProcessPoolExecutor(max_workers=1)
def task() -> None:
"""."""
print("Executed in process pool")
@app.get("/")
def index() -> Dict[str, Any]:
"""Index."""
POOL.submit(task)
return {"message": "Hello World"}
Expected behavior
Uvicorn should reload when file changes are detected.
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [9042] using watchgod
INFO: Started server process [9044]
INFO: Waiting for application startup.
INFO: Application startup complete.
WARNING: WatchGodReload detected file change in '['/Users/maartenhuijsmans/main.py']'. Reloading...
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [9044]
INFO: Started server process [9047]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:61607 - "GET / HTTP/1.1" 200 OK
Actual behavior
Uvicorn doesn’t start
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [9054] using watchgod
INFO: Started server process [9056]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: 127.0.0.1:61615 - "GET / HTTP/1.1" 200 OK
Executed in process pool
WARNING: WatchGodReload detected file change in '['/Users/maartenhuijsmans/main.py']'. Reloading...
INFO: Shutting down
INFO: Waiting for application shutdown.
INFO: Application shutdown complete.
INFO: Finished server process [9056]
Debugging material
Environment
- macOS 10.13.6 / python 3.8.6 / uvicorn 0.13.3
uvicorn main:app --reload
Additional context
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
api - Problem enabling Uvicorn auto-restart when launching ...
The documentation states that you can just use reload=True . Example: uvicorn.run("example:app", port=5000, reload=True, access_log=False).
Read more >Settings - Uvicorn
When using Uvicorn through WSL, you might have to set the WATCHFILES_FORCE_POLLING environment variable, for file changes to trigger a reload. See watchfiles ......
Read more >bocadilloproject/bocadillo - Gitter
If I run uvicorn asgi:app --reload in the second demo subdirectory, it errors: ... can't use in Python unless you're running from outside...
Read more >Gunicorn - Hacker News
I have been using Gunicorn with Gevent for nearly 10 years and never had a problem ... The sockets would very silently crash...
Read more >Falcon Documentation - Read the Docs
Uvicorn is a popular choice, owing to its fast and stable implementation ... Restart Gunicorn (unless you're using --reload), and send a GET ......
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
incidentally it seems to not happen on #853
This is not a bug. It works as intended.
On the
BaseReload.restart()
method, weterminate()
the server process, and then wejoin()
. As the process still have theProcessPool
alive, it will never terminate.That said, we have two options:
join()
accepts a timeout parameter, we can set it to a value that makes sense (?).shutdown
event.On
2
you’d have:Given that the snippet above already satisfies this issue, and that I’ve provided explanation about what’s happening, I’ll be closing this issue. If there’s a good argument, and a proposal to implement
1
inuvicorn
, we can reconsider it.