fix: evict stale project engine delegate on delete to prevent assert self._db crash

Deleting a project closed its store but left the delegate cached in
_project_engine_delegates; re-creating a same-name project then reused the
zombie engine and crashed in get_session. delete() now closes and evicts via
_close_project_engine_store (also covers non-active deletes), the delegate
cache self-heals when a cached store is closed, and _engine_for_project
reopens a closed store for the non-evictable root engine case.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
LZH-YS1998
2026-07-07 18:45:46 +08:00
parent a30fa7588d
commit 47e9b2c488
3 changed files with 29 additions and 8 deletions
+9
View File
@@ -763,6 +763,15 @@ class WSHandler:
)
maybe_engine = delegate_getter(normalized)
engine = await maybe_engine if inspect.isawaitable(maybe_engine) else maybe_engine
# Self-heal a closed store (project deleted then re-created while this
# engine instance stayed bound to it — e.g. the root engine, which can
# never be evicted from its own delegate cache).
store = getattr(engine, "store", None)
if store is not None and not getattr(store, "is_ready", True):
ensure_ready = getattr(store, "ensure_ready", None)
if callable(ensure_ready):
logger.warning(f"Reopening closed store for project '{normalized}'")
await ensure_ready()
self._wire_engine_callbacks(engine)
return engine