Repository navigation
refactor(slack-bridge): mtime-based cache for load_allowed/load_tier_map (closes #894) - #1186
bassilkhilo-ag2 wants to merge 1 commit into
Conversation
…map (closes sonichi#894) Both helpers read access.json on every _write_task invocation — wasteful for a long-running daemon even at low Slack volume. Introduce _load_access_json() that checks stat().st_mtime before re-parsing; load_allowed() and load_tier_map() are now thin wrappers. The None-vs-set TOFU contract is preserved (file absent → allowed=None in the shared helper). Tests: 19/19 pass in slack-bridge-tier-map.test.py (5 new cache cases); slack-bridge-access.test.py updated to accept both the pre-sonichi#894 direct-return shape and the new helper-delegation shape. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
VasiliyRad
left a comment
There was a problem hiding this comment.
Cache logic is correct. The stat/read outside the lock is safe — a race between stat and read at best causes one extra parse on a file-changed boundary, which is harmless and self-correcting on the next call. TOFU contract preserved: allowed=None on missing file flows through correctly. Tests cover the four meaningful states (cache hit, mtime bump, file deleted). Scope is clean — only src/slack-bridge.py and its two test files.
VasiliyRad
left a comment
There was a problem hiding this comment.
Clean refactor. _load_access_json() reads + parses once per mtime tick; both load_allowed() and load_tier_map() are thin delegates now. Thread-safety via _access_cache_lock, OSError handling preserved, and the load-bearing None-vs-empty-set distinction for TOFU eligibility is intact (file-missing → None, parse-error → empty set). Tests updated to match the new shape. 3 files only, no bundled changes.
LGTM 👍
Summary
load_allowed()andload_tier_map()both readaccess.jsonon every_write_taskcall — O(N) I/O for N Slack events in a long-running daemon_load_access_json(): checksstat().st_mtimebefore re-parsing; only re-reads when the file changes[0]/[1]from the cached tupleNonevsset()TOFU contract is preserved (allowed = Nonewhen file absent, in the shared helper)Tests
tests/slack-bridge-tier-map.test.py: 5 new cache tests (same-mtime returns identical object, mtime bump invalidates, deleted file → None/{}). 19/19 pass.tests/slack-bridge-access.test.py: structural check updated to accept both the pre-slack-bridge: cache load_tier_map() instead of re-reading on every _write_task call [priority/low] #894except FileNotFoundError: return Noneshape and the new_load_access_json()delegation shape. Still passes.Test plan
python3 tests/slack-bridge-tier-map.test.py→ 19 passedpython3 tests/slack-bridge-access.test.py→ 1 passed🤖 Generated with Claude Code