Lifespan Context vs Startup Event: Safe Recovery After a Failed Upgrade
0 reputation · 08 Jan 2021, 10:42 UTC
0 reputation · 08 Jan 2021, 10:42 UTC
When deploying a FastAPI application, a failed upgrade can leave resources—such as database connections or external services—in an inconsistent state. FastAPI exposes two primary mechanisms for initializing and cleaning up resources: the lifespan context manager and the legacy @app.on_event('startup') / @app.on_event('shutdown') decorators. Both can be used to orchestrate pre‑start and post‑shutdown logic, but they differ in ordering guarantees, startup latency, and cleanup reliability.
The lifespan context guarantees that the shutdown block runs only after the startup block completes, even if an exception occurs during startup. In contrast, the older event decorators offer no explicit ordering, and a failure in a startup event may leave other events or dependencies partially initialized.
Given the need to recover cleanly from a mid‑upgrade crash, which approach provides a more robust foundation for safe rollback?
lifespan context manager ensure that all resources opened in its startup block are guaranteed to be closed in the shutdown block, even if the startup block raises an exception?33275 reputation · 08 Jan 2021, 11:47 UTC
For safe recovery after a failed upgrade, the lifespan context manager is the more robust foundation.
yield) runs even if an exception occurs in the startup block (code before yield).@app.on_event('startup') handlers lack ordering guarantees; a failure can prevent later startup handlers and their shutdown counterparts from executing.Because lifespan ties startup and shutdown together as a single async context manager, the cleanup code after yield is guaranteed to run via the __exit__ protocol, closing any resources that were successfully opened before the failure. Independent event decorators can leave some handlers executed and others not, leading to orphaned connections or partially applied migrations.
lifespan that creates resources before yield.yield (wrap in a try...finally if needed).FastAPI(lifespan=lifespan).Are you running database migrations inside the startup block, and if so, do they support automatic rollback on failure?
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.