Skip to content

Commit 28be9fe

Browse files
fix: share workspace_storage_fingerprint and guard cache writes
1 parent e89f46b commit 28be9fe

5 files changed

Lines changed: 16 additions & 33 deletions

File tree

services/export_engine.py

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
from models import Bubble
1414
from models.export import CollectedExportEntry
15-
from services.summary_cache import fingerprint_workspace_storage, nocache_enabled
15+
from services.summary_cache import nocache_enabled
1616
from services.workspace_context import (
1717
WorkspaceContext,
1818
enrich_workspace_context_from_global_db,
@@ -22,7 +22,6 @@
2222
from services.workspace_db import (
2323
COMPOSER_ROWS_WITH_HEADERS_SQL,
2424
collect_workspace_entries,
25-
global_storage_db_path,
2625
load_code_block_diff_map,
2726
open_global_db,
2827
safe_fetchall,
@@ -84,7 +83,6 @@ class WorkspaceOrchestration:
8483

8584
workspace_path: str
8685
workspace_entries: list[dict[str, Any]]
87-
fingerprint: dict[str, Any]
8886
ctx: WorkspaceContext
8987
workspace_id_to_display_name: dict[str, str]
9088
workspace_id_to_slug: dict[str, str]
@@ -135,21 +133,12 @@ def prepare_workspace_orchestration(
135133
nocache: bool = False,
136134
workspace_entries: list[dict[str, Any]] | None = None,
137135
) -> WorkspaceOrchestration:
138-
"""Scan workspace storage and resolve maps (with summary-cache fingerprint)."""
136+
"""Scan workspace storage and resolve maps for listing and export."""
139137
entries = (
140138
workspace_entries
141139
if workspace_entries is not None
142140
else collect_workspace_entries(workspace_path)
143141
)
144-
gdb = global_storage_db_path(workspace_path)
145-
cli_path = get_cli_chats_path()
146-
fingerprint = fingerprint_workspace_storage(
147-
workspace_path,
148-
entries,
149-
global_db_path=gdb if os.path.isfile(gdb) else None,
150-
rules=rules,
151-
cli_chats_path=cli_path if os.path.isdir(cli_path) else None,
152-
)
153142
ctx = resolve_workspace_context_cached(
154143
workspace_path,
155144
rules,
@@ -160,7 +149,6 @@ def prepare_workspace_orchestration(
160149
return WorkspaceOrchestration(
161150
workspace_path=workspace_path,
162151
workspace_entries=entries,
163-
fingerprint=fingerprint,
164152
ctx=ctx,
165153
workspace_id_to_display_name=display_name,
166154
workspace_id_to_slug=slug_map,

services/search_index.py

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
)
3030
from services.summary_cache import (
3131
CACHE_DIR,
32-
fingerprint_workspace_storage,
3332
nocache_enabled,
33+
workspace_storage_fingerprint,
3434
)
3535
from services.workspace_db import (
3636
COMPOSER_ROWS_WITH_HEADERS_SQL,
@@ -40,7 +40,6 @@
4040
)
4141
from utils.path_helpers import to_epoch_ms
4242
from utils.exclusion_rules import RuleTokens
43-
from utils.workspace_path import get_cli_chats_path
4443

4544
__all__ = [
4645
"SEARCH_INDEX_FILE",
@@ -130,15 +129,7 @@ def index_search_enabled() -> bool:
130129

131130
def _storage_fingerprint(workspace_path: str, rules: list[RuleTokens]) -> dict[str, Any]:
132131
entries = collect_workspace_entries(workspace_path)
133-
gdb = global_storage_db_path(workspace_path)
134-
cli_path = get_cli_chats_path()
135-
return fingerprint_workspace_storage(
136-
workspace_path,
137-
entries,
138-
global_db_path=gdb if os.path.isfile(gdb) else None,
139-
rules=rules,
140-
cli_chats_path=cli_path if os.path.isdir(cli_path) else None,
141-
)
132+
return workspace_storage_fingerprint(workspace_path, entries, rules)
142133

143134

144135
def _open_index_db(*, readonly: bool = True) -> sqlite3.Connection | None:

services/summary_cache.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def _entry_mtimes(entry: dict[str, Any]) -> list[list[str | int]]:
115115
}
116116

117117

118-
def _workspace_storage_fingerprint(
118+
def workspace_storage_fingerprint(
119119
workspace_path: str,
120120
workspace_entries: list[dict[str, Any]],
121121
rules: list[RuleTokens],
@@ -260,20 +260,25 @@ def _get_or_build_cached(
260260
should_cache: Callable[[T], bool] | None = None,
261261
) -> T:
262262
with _summary_cache_lock:
263-
fingerprint = _workspace_storage_fingerprint(workspace_path, workspace_entries, rules)
264-
hit = get_unlocked(fingerprint)
263+
pre_fingerprint = workspace_storage_fingerprint(
264+
workspace_path, workspace_entries, rules,
265+
)
266+
hit = get_unlocked(pre_fingerprint)
265267
if hit is not None:
266268
return hit
267269

268270
built = build_fn()
269271

270272
with _summary_cache_lock:
271-
fingerprint = _workspace_storage_fingerprint(workspace_path, workspace_entries, rules)
272-
hit = get_unlocked(fingerprint)
273+
post_fingerprint = workspace_storage_fingerprint(
274+
workspace_path, workspace_entries, rules,
275+
)
276+
hit = get_unlocked(post_fingerprint)
273277
if hit is not None:
274278
return hit
275279
if should_cache is None or should_cache(built):
276-
set_unlocked(fingerprint, built)
280+
if _fingerprint_equal(pre_fingerprint, post_fingerprint):
281+
set_unlocked(pre_fingerprint, built)
277282
return built
278283

279284

tests/test_export_engine.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ def _minimal_orch(
6464
return WorkspaceOrchestration(
6565
workspace_path=tmp_ws,
6666
workspace_entries=[],
67-
fingerprint={},
6867
ctx=_minimal_ctx(),
6968
workspace_id_to_display_name=display_name or {},
7069
workspace_id_to_slug=slug_map or {},

tests/test_summary_cache_concurrency.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ def test_concurrent_get_or_build_returns_consistent_results(self):
142142
warm_projects = [
143143
{"id": "warm", "name": "Warm", "conversationCount": 2, "lastModified": "z"},
144144
]
145-
fingerprint = summary_cache._workspace_storage_fingerprint(
145+
fingerprint = summary_cache.workspace_storage_fingerprint(
146146
workspace_path,
147147
workspace_entries, # type: ignore[arg-type]
148148
[],

0 commit comments

Comments
 (0)