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
+5 -6
View File
@@ -240,14 +240,13 @@ class ProjectService:
deleted_channels = int(await delete_chat(project_id) or 0)
logger.info(f"Deleted {deleted_channels} channels for project '{project_id}'")
# Close every engine bound to this project AND evict its delegate from
# the root engine's cache; a stale delegate would otherwise be reused
# (with a closed store) if a project with the same id is re-created.
await self._close_project_engine_store(project_id)
projects_dir = self.context.project_dir(project_id)
if projects_dir.is_dir():
active_engine = self.context.engine
if was_active and getattr(active_engine, "store", None):
try:
await active_engine.store.close()
except Exception:
logger.opt(exception=True).debug("Failed to close active project store before delete")
shutil.rmtree(str(projects_dir), ignore_errors=True)
workplace = self.context.project_workplace(project_id)