@@ -89,6 +89,8 @@ def create_app( |
| 89 | a TestClient. | 89 | a TestClient. |
| 90 | """ | 90 | """ |
| 91 | try: | 91 | try: |
| | 92 | + from contextlib import asynccontextmanager |
| | 93 | + |
| 92 | from fastapi import FastAPI, HTTPException, Request, status | 94 | from fastapi import FastAPI, HTTPException, Request, status |
| 93 | from fastapi.responses import JSONResponse | 95 | from fastapi.responses import JSONResponse |
| 94 | except ImportError as exc: | 96 | except ImportError as exc: |
@@ -102,6 +104,18 @@ def create_app( |
| 102 | request_count = 0 | 104 | request_count = 0 |
| 103 | total_run_seconds = 0.0 | 105 | total_run_seconds = 0.0 |
| 104 | | 106 | |
| | 107 | + # Capture cache in the lifespan closure so the shutdown leg runs |
| | 108 | + # ``evict_all`` (the on_event API is deprecated in FastAPI 0.110+). |
| | 109 | + _cache_for_lifespan = cache |
| | 110 | + |
| | 111 | + @asynccontextmanager |
| | 112 | + async def _lifespan(app: Any) -> Any: |
| | 113 | + del app |
| | 114 | + try: |
| | 115 | + yield |
| | 116 | + finally: |
| | 117 | + _cache_for_lifespan.evict_all() |
| | 118 | + |
| 105 | app = FastAPI( | 119 | app = FastAPI( |
| 106 | title="sway", | 120 | title="sway", |
| 107 | version=__version__, | 121 | version=__version__, |
@@ -109,6 +123,7 @@ def create_app( |
| 109 | "Warm-backend HTTP API for sway. POST /run accepts a spec; " | 123 | "Warm-backend HTTP API for sway. POST /run accepts a spec; " |
| 110 | "the daemon keeps backends loaded between calls." | 124 | "the daemon keeps backends loaded between calls." |
| 111 | ), | 125 | ), |
| | 126 | + lifespan=_lifespan, |
| 112 | ) | 127 | ) |
| 113 | | 128 | |
| 114 | # -- auth middleware -------------------------------------------------- | 129 | # -- auth middleware -------------------------------------------------- |
@@ -265,12 +280,6 @@ def create_app( |
| 265 | "request_seconds": elapsed, | 280 | "request_seconds": elapsed, |
| 266 | } | 281 | } |
| 267 | | 282 | |
| 268 | - # -- shutdown -------------------------------------------------------- | | |
| 269 | - | | |
| 270 | - @app.on_event("shutdown") | | |
| 271 | - async def _on_shutdown() -> None: | | |
| 272 | - cache.evict_all() | | |
| 273 | - | | |
| 274 | # Stash the cache + counters on the app so tests can introspect. | 283 | # Stash the cache + counters on the app so tests can introspect. |
| 275 | app.state.sway_cache = cache | 284 | app.state.sway_cache = cache |
| 276 | | 285 | |