fix(mcp): avoid Chroma open when cached DB disappears
This commit is contained in:
parent
6c5e1be3db
commit
97ba05cfe3
|
|
@ -164,10 +164,10 @@ def _get_result_ids(result) -> list:
|
|||
if ids is not None:
|
||||
return ids
|
||||
if isinstance(result, dict):
|
||||
return result.get("ids", [])
|
||||
return result.get("ids") or []
|
||||
getter = getattr(result, "get", None)
|
||||
if callable(getter):
|
||||
return getter("ids", [])
|
||||
return getter("ids") or []
|
||||
return []
|
||||
|
||||
|
||||
|
|
@ -361,6 +361,7 @@ def _force_chroma_cache_reset() -> None:
|
|||
_palace_db_mtime, \
|
||||
_metadata_cache, \
|
||||
_metadata_cache_time
|
||||
cached_client = _client_cache
|
||||
_client_cache = None
|
||||
_collection_cache = None
|
||||
_collection_cache_backend = None
|
||||
|
|
@ -376,7 +377,24 @@ def _force_chroma_cache_reset() -> None:
|
|||
backend = get_backend_for_palace(_config.palace_path)
|
||||
backend.close_palace(PalaceRef(id=_config.palace_path, local_path=_config.palace_path))
|
||||
except Exception:
|
||||
pass
|
||||
logger.debug("Failed to close cached Chroma backend during cache reset", exc_info=True)
|
||||
if cached_client is not None:
|
||||
try:
|
||||
close = getattr(cached_client, "close", None)
|
||||
if callable(close):
|
||||
close()
|
||||
except Exception:
|
||||
logger.debug(
|
||||
"Failed to close MCP-local Chroma client during cache reset", exc_info=True
|
||||
)
|
||||
try:
|
||||
from chromadb.api.client import SharedSystemClient
|
||||
|
||||
clear_system_cache = getattr(SharedSystemClient, "clear_system_cache", None)
|
||||
if callable(clear_system_cache):
|
||||
clear_system_cache()
|
||||
except Exception:
|
||||
logger.debug("Failed to clear Chroma shared system cache during cache reset", exc_info=True)
|
||||
|
||||
|
||||
# ── Vector-search disabled flag (#1222) ──────────────────────────────────
|
||||
|
|
@ -687,6 +705,16 @@ def _get_collection(create=False):
|
|||
}
|
||||
return None
|
||||
|
||||
db_path = os.path.join(_config.palace_path, "chroma.sqlite3")
|
||||
if not create and not os.path.isfile(db_path):
|
||||
_force_chroma_cache_reset()
|
||||
_collection_open_error = {
|
||||
"error": "Chroma database missing",
|
||||
"details": f"Could not open missing database at {db_path}.",
|
||||
"hint": "Run: mempalace status or mempalace repair-status for diagnostics.",
|
||||
}
|
||||
return None
|
||||
|
||||
for attempt in range(2):
|
||||
try:
|
||||
if _collection_cache is not None and (
|
||||
|
|
|
|||
|
|
@ -1239,6 +1239,16 @@ class TestWriteTools:
|
|||
assert result["reason"] == "already_exists"
|
||||
mock_col.upsert.assert_not_called()
|
||||
|
||||
def test_get_result_ids_normalizes_none_to_empty_list(self):
|
||||
from mempalace import mcp_server
|
||||
|
||||
class DictLikeResult:
|
||||
def get(self, key, default=None):
|
||||
return None
|
||||
|
||||
assert mcp_server._get_result_ids({"ids": None}) == []
|
||||
assert mcp_server._get_result_ids(DictLikeResult()) == []
|
||||
|
||||
def test_add_drawer_fails_when_readback_misses(self, monkeypatch, config, kg):
|
||||
_patch_mcp_server(monkeypatch, config, kg)
|
||||
from mempalace import mcp_server
|
||||
|
|
@ -2385,10 +2395,20 @@ class TestCacheInvalidation:
|
|||
if os.path.isfile(db_file):
|
||||
os.remove(db_file)
|
||||
|
||||
make_client_calls = []
|
||||
|
||||
def fail_if_make_client_called(path):
|
||||
make_client_calls.append(path)
|
||||
raise AssertionError("_get_collection(create=False) should not open missing Chroma DB")
|
||||
|
||||
monkeypatch.setattr(mcp_server.ChromaBackend, "make_client", fail_if_make_client_called)
|
||||
|
||||
# Cache should be invalidated; _get_collection returns None
|
||||
# because the backend can't open a missing DB without create=True
|
||||
mcp_server._get_collection()
|
||||
assert mcp_server._get_collection() is None
|
||||
# The key assertion: the old cached collection was dropped
|
||||
assert make_client_calls == []
|
||||
assert mcp_server._collection_cache is None
|
||||
assert mcp_server._palace_db_inode == 0
|
||||
assert mcp_server._palace_db_mtime == 0.0
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue