fix(hooks): atomic flush + hook timing wiring (#1493, #1494)#1496
Merged
Conversation
Replace separate _locked_read() + _locked_write() in flush() with a single _locked_modify() helper that holds LOCK_EX for the entire read-modify-write window. This prevents concurrent PostToolUse processes from clobbering each other's updates. Add TestConcurrentFlush regression test (8 procs × 100 calls = 800 expected) that fails without the fix.
- Add hooks/lib/hook_runtime.py with time_hook() context manager that records hook elapsed time via SessionStats.record_hook_timing() - Wire time_hook into all 5 hook scripts: PreToolUse, PostToolUse, SessionStart, Stop, UserPromptSubmit - Delete hooks/lib/hook_timer.py (dead code — per-process in-memory model does not work for short-lived hook processes) - Delete tests/test_hook_timer.py (tests for removed dead code) - Add TestHookTimingWiring regression tests (3 cases): recording, exception resilience, accumulation The Stop hook summary now surfaces ⏱ timing data: [CB] 3m | 12 tools | 0 errors | Bash:5 | ⏱ PostToolUse:42ms
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
_locked_read()+_locked_write()inSessionStats.flush()with atomic_locked_modify()helper that holdsLOCK_EXfor the entire read-modify-write window, preventing concurrent PostToolUse processes from clobbering each other's updateshooks/lib/hook_runtime.pywithtime_hook()context manager; wire it into all 5 hook scripts (PreToolUse, PostToolUse, SessionStart, Stop, UserPromptSubmit) so the Stop hook summary now surfaces⏱timing datahooks/lib/hook_timer.pyand its tests — per-process in-memory model doesn't work for short-lived hook processes;SessionStats.record_hook_timing()is the correct cross-process approachTest plan
TestConcurrentFlush: 8 processes × 100 calls = 800 expected, asserts exact count (fails without race fix, passes with_locked_modify)TestHookTimingWiring: 3 tests — recording, exception resilience, accumulationtest_stats.pypasspackages/claude-code-plugin/tests/pass (2 pre-existing failures intest_hud.pyunrelated to this PR — buddy face character mismatch)⏱ PostToolUse:Xmsappears in Stop hook summary during a real Claude Code sessionCloses #1493
Closes #1494