fix(sessions): debounce and dedup watch() emissions Refs #815#860
fix(sessions): debounce and dedup watch() emissions Refs #815#860AlexMikhalev wants to merge 1 commit intomainfrom
Conversation
Prevent NativeTerraphim AIConnector::watch() from emitting a duplicate session on every Modify inotify event. The new watch_at() implementation: - Collects fileSystem events into a per-path pending map; only flushes a path after a 200 ms quiescent window with no further events (debounce). - Tracks messages.len() at last emission per path (last_emitted map) and skips emission when the count has not grown (content dedup). - Runs the notify event loop synchronously inside spawn_blocking, using tx.blocking_send() to avoid nested tokio::spawn on single-threaded test runtimes. - Adds parse_session_file_sync() as the blocking-thread counterpart to the async parse_session_file() method. Unit test test_parse_session_file_sync_dedup_key() verifies the dedup key invariant without requiring a live fileSystem watcher. The end-to-end watch integration test is marked #[ignore] with an explanatory comment (timing-sensitive; run manually with -- --ignored). Co-Authored-By: Terraphim AI <noreply@terraphim.ai>
Requirements Traceability SummaryPR #860 fixes a behavioural regression in Scope: single crate Verdict: concernsImplementation is clean and the unit test is solid. Two gaps reduce confidence: (1) no originating issue or ADR captures the Traceability Matrix
GapsBlockers
Follow-ups
Last spec-validated commit: 202042c |
Summary
NativeTerraphim AIConnector::watch()previously emitted a duplicate session on everyModifyinotify event, once per JSONL line-flushmessages.len()unchanged)Changes
connector/native.rswatch_at(base_path)private method for testable path injection, containing all debounce + dedup logicwatch()delegates towatch_at(default_path)pending: HashMap<PathBuf, Instant>— per-path debounce clock; flush only after 200 ms silencelast_emitted: HashMap<PathBuf, usize>— tracksmessages.len()at last emission; skips if unchangedspawn_blocking; usesparse_session_file_sync+tx.blocking_send()to avoid nested-spawn stalltx.is_closed()connector/mod.rswatch()trait doc with formal Deduplication contractTests
test_parse_session_file_sync_dedup_key— unit test verifying dedup invariant without fileSystem watchertest_watch_deduplicates_incremental_appends— end-to-end watch test marked#[ignore](inotify/tmpfs timing-sensitive); run manually with-- --ignoredVerification