fix: keep pooled live snapshots cancellation-safe (#137)
This commit is contained in:
1 parent
efb3ae3400
commit
0dc5c2c831
3 files changed
+135
-3
No files matched your search
+22
-3
@@ -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(
|
||||
|
||||
Reference in new issue
Block a user