Fix cleanup coordination between Gunicorn and UvicornWorker lifecycles

• Document UvicornWorker hook limitations
• Add GUNICORN_CMD_ARGS cleanup guard
• Prevent double cleanup in workers
This commit is contained in:
yangdx 2025-10-29 13:53:46 +08:00
parent 72b29659c9
commit 816feefd84
2 changed files with 21 additions and 4 deletions

View file

@ -168,8 +168,21 @@ def worker_exit(server, worker):
""" """
Executed when a worker is about to exit. Executed when a worker is about to exit.
This is called for each worker process when it exits. We should only NOTE: When using UvicornWorker (worker_class = "uvicorn.workers.UvicornWorker"),
clean up worker-local resources here, NOT the shared Manager. this hook may NOT be called reliably. UvicornWorker has its own lifecycle
management that prioritizes ASGI lifespan shutdown events.
The primary cleanup mechanism is handled by:
1. FastAPI lifespan context manager with GUNICORN_CMD_ARGS check (in lightrag_server.py)
- Workers skip cleanup when GUNICORN_CMD_ARGS is set
2. on_exit() hook for main process cleanup
This function serves as a defensive fallback for:
- Non-UvicornWorker scenarios
- Future Gunicorn/Uvicorn behavior changes
- Additional safety layer
When called, we should only clean up worker-local resources, NOT the shared Manager.
The Manager should only be shut down by the main process in on_exit(). The Manager should only be shut down by the main process in on_exit().
""" """
print("=" * 80) print("=" * 80)

View file

@ -326,8 +326,12 @@ def create_app(args):
# Clean up database connections # Clean up database connections
await rag.finalize_storages() await rag.finalize_storages()
# Clean up shared data # In Gunicorn mode with preload_app=True, cleanup is handled by worker_exit/on_exit hooks
finalize_share_data() # Only perform cleanup in Uvicorn single-process mode
if "GUNICORN_CMD_ARGS" not in os.environ:
# Clean up shared data
finalize_share_data()
# Initialize FastAPI # Initialize FastAPI
base_description = ( base_description = (