td-6ad8cd

merchant-kb MCP: atomic-swap reload to eliminate reader race

open task P3 Parent: td-5a8ff4
Created Apr 16, 2026 6:49 PM Updated Apr 16, 2026 6:49 PM
Description
_ensure_fresh() in product-toolkit/mcp-servers/merchant-kb/server.py currently clears shared globals in place, then _load() re-populates them. A reader thread that starts iterating _index, _reviews, etc. during the clear+reload window could see empty or partial state. Mitigation in place: threading.Lock serializes reload so concurrent reloads can't duplicate entries. The reader-window race is narrow (only when a new daily-sync commit lands and multiple requests arrive within the reload window). Proper fix: refactor _load() to build fresh local structures, then atomically rebind globals (Python assignments are GIL-atomic at the attribute level). Requires restructuring _load() which currently mutates globals directly. Flagged by codex in second-pass review of the cache-staleness fix (2026-04-16).
Session Log (0 entries)