fix: keep pooled live snapshots cancellation-safe (#137)
CI / lint (pull_request) Successful in 10s
CI / build-frontend (pull_request) Successful in 5s

This commit is contained in:
timmy committed 2026-08-06 20:51:53 +00:00
1 parent efb3ae3400
commit 0dc5c2c831
3 files changed
+135 -3

No files matched your search

+22 -3
View File
@@ -26,11 +26,23 @@ from src.views import router as frontend_router
@asynccontextmanager
async def lifespan(_app: FastAPI):
global _live_snapshot_task
gitea_proxy.start_client()
try:
yield
finally:
await gitea_proxy.stop_client()
task = _live_snapshot_task
if task is not None and not task.done():
task.cancel()
try:
await task
except asyncio.CancelledError:
pass
try:
await gitea_proxy.stop_client()
finally:
if _live_snapshot_task is task:
_live_snapshot_task = None
app = FastAPI(title="Stackchain Dashboard", lifespan=lifespan)
@@ -251,15 +263,22 @@ async def _build_live_snapshot() -> dict:
}
async def _build_live_snapshot_before_deadline() -> dict:
async with asyncio.timeout(CONTEXT_TIMEOUT_SECONDS):
return await _build_live_snapshot()
@app.get("/api/v1/live")
async def live_snapshot() -> JSONResponse:
"""Return a fresh, section-aware snapshot; join only an active identical load."""
global _live_snapshot_task
if _live_snapshot_task is None or _live_snapshot_task.done():
_live_snapshot_task = asyncio.create_task(_build_live_snapshot())
_live_snapshot_task = asyncio.create_task(
_build_live_snapshot_before_deadline()
)
task = _live_snapshot_task
try:
result = await asyncio.wait_for(task, timeout=CONTEXT_TIMEOUT_SECONDS)
result = await asyncio.shield(task)
return JSONResponse(result)
except TimeoutError:
return JSONResponse(