Coalesce index generation increments and add rebuild cooldown
This commit is contained in:
@@ -379,9 +379,14 @@ async def _on_vault_change(events: list):
|
||||
Processes each event (create/modify/delete/move) and updates the index
|
||||
incrementally, then broadcasts SSE notifications.
|
||||
"""
|
||||
import backend.indexer as idx
|
||||
updated_vaults = set()
|
||||
changes = []
|
||||
|
||||
# Temporarily suppress per-file generation increments to coalesce them
|
||||
# into a single increment at the end of the batch.
|
||||
old_gen = idx._index_generation
|
||||
|
||||
for event in events:
|
||||
vault_name = event["vault"]
|
||||
event_type = event["type"]
|
||||
@@ -410,6 +415,11 @@ async def _on_vault_change(events: list):
|
||||
except Exception as e:
|
||||
logger.error(f"Error processing {event_type} event for {src}: {e}")
|
||||
|
||||
# Restore generation to only increment by 1 for the whole batch
|
||||
# (unless it was already incremented by other operations)
|
||||
if idx._index_generation > old_gen + 1:
|
||||
idx._index_generation = old_gen + 1
|
||||
|
||||
if changes:
|
||||
await sse_manager.broadcast("index_updated", {
|
||||
"vaults": list(updated_vaults),
|
||||
|
||||
+13
-4
@@ -265,15 +265,22 @@ class InvertedIndex:
|
||||
self.tag_docs: Dict[str, set] = defaultdict(set)
|
||||
self._sorted_tokens: List[str] = []
|
||||
self._source_generation: int = -1
|
||||
self._last_rebuild: float = 0
|
||||
self._rebuild_cooldown: float = 3.0 # seconds
|
||||
|
||||
def is_stale(self) -> bool:
|
||||
"""Check if the inverted index needs rebuilding.
|
||||
|
||||
Uses the indexer's generation counter which increments on every
|
||||
rebuild, instead of ``id(index)`` which never changes since the
|
||||
global dict is mutated in-place.
|
||||
Uses a cooldown (3s) to prevent rapid rebuilds from file watcher
|
||||
events. Staleness is only reported if the generation has changed
|
||||
AND the cooldown has elapsed since the last rebuild.
|
||||
"""
|
||||
return _indexer._index_generation != self._source_generation
|
||||
import time
|
||||
if _indexer._index_generation == self._source_generation:
|
||||
return False
|
||||
if time.time() - self._last_rebuild < self._rebuild_cooldown:
|
||||
return False
|
||||
return True
|
||||
|
||||
def rebuild(self) -> None:
|
||||
"""Rebuild inverted index from the global ``index`` dict.
|
||||
@@ -281,6 +288,8 @@ class InvertedIndex:
|
||||
Tokenizes titles and content of every file, computes term frequencies,
|
||||
and builds auxiliary indexes for tag and title prefix suggestions.
|
||||
"""
|
||||
import time
|
||||
self._last_rebuild = time.time()
|
||||
logger.info("Rebuilding inverted index...")
|
||||
self.word_index = defaultdict(dict)
|
||||
self.title_index = defaultdict(list)
|
||||
|
||||
Reference in New Issue
Block a user