fix: /api/diagnostics 500 « dictionary changed size during iteration » (snapshot des dicts avant itération)
This commit is contained in:
@@ -460,6 +460,39 @@ class TestConfig:
|
||||
# Should have some diagnostic info
|
||||
assert len(data) > 0
|
||||
|
||||
def test_diagnostics_concurrent_index_writes(self, client):
|
||||
"""Regression: word_index mutated while the handler iterates it raised
|
||||
"dictionary changed size during iteration" -> 500."""
|
||||
from backend.search import get_inverted_index
|
||||
|
||||
inv = get_inverted_index()
|
||||
original = inv.word_index
|
||||
|
||||
class RaceDict(dict):
|
||||
"""dict whose .values() grows the dict mid-iteration, exactly like
|
||||
the indexer writing from another thread."""
|
||||
def values(self):
|
||||
it = iter(dict.values(self))
|
||||
first = next(it, _SENTINEL)
|
||||
if first is _SENTINEL:
|
||||
return iter(())
|
||||
self["__injected__"] = {"__injected_doc__": 1}
|
||||
|
||||
def gen():
|
||||
yield first
|
||||
yield from it # raises RuntimeError: dict changed size
|
||||
return gen()
|
||||
|
||||
_SENTINEL = object()
|
||||
inv.word_index = RaceDict(original)
|
||||
try:
|
||||
resp = client.get("/api/diagnostics")
|
||||
assert resp.status_code == 200, resp.text
|
||||
assert "memory_estimate_mb" in resp.json()["inverted_index"]
|
||||
finally:
|
||||
inv.word_index = original
|
||||
original.pop("__injected__", None)
|
||||
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════
|
||||
# Dashboard
|
||||
|
||||
Reference in New Issue
Block a user