mirror of
https://github.com/stablyai/orca.git
synced 2026-11-03 18:47:40 +00:00
* perf(watcher): flush file changes on a steady cadence instead of waiting for quiet Watcher batches used a 150 ms trailing debounce capped at 500 ms, so a worktree with agents writing continuously always waited the full cap. The git status nudge had no cap and could starve until the 60 s safety poll. Batches now flush 25 ms after the first change following a quiet period, then at most every 100 ms; new events join an armed flush instead of pushing it back. * fix(watcher): keep atomic saves in one batch and survive clock jumps Raise the first-flush delay to 75 ms so the native watcher's split burst lands in one batch, cap the flush delay at one interval so a backwards clock jump can't stall delivery, and widen the editor delete debounce to cover a split across one flush interval. * test: wait past the widened editor delete debounce * fix(watcher): keep markdown list refreshing under sustained writes and widen delete grace Markdown document refresh used a resetting 125 ms debounce that never fired once watch batches arrive every 100 ms. Delete tombstones now wait two batch intervals so slow stat calls (WSL, AV scans) can't split a save into a flash. * fix(watcher): bound watcher-driven reads and scans under sustained writes One watcher-triggered editor read and one markdown scan per target in flight, with a single follow-up; markdown scans honour the latest change time; the headless Windows watcher no longer resets its refresh timer on every event. * fix(watcher): make the faster remote cadence opt-in and harden watcher-driven reloads files.watch takes an optional batchCadence; hosts keep legacy trailing batching unless the client opts in. Coalesced editor follow-ups re-check the tab and replace a hung read only once; Markdown mounts skip pre-change scans; the Windows fallback refreshes the whole tree at most every 500 ms. * fix(watcher): stop restarting the remaining watch-driven timers Combined-diff section reloads and per-file editor reload dispatch no longer push an armed timer back; a queued editor follow-up for a tab that left the screen marks it stale instead of dropping the change. * fix(watcher): let combined-diff and worktree notifications land under sustained writes A combined-diff section discards an invalidated in-flight load at most once in a row; worktree base-directory notifications no longer restart their timer. * fix(watcher): never overwrite an edited diff section and unstick hung reloads A combined-diff load never commits over a section with unsaved edits; a reload queued behind a hung read starts after the stale limit without needing another change event. * fix(watcher): recover from hung markdown scans and keep evidence for edited tabs A Markdown scan that never settles is abandoned after the join window so later changes scan again; a queued editor follow-up for a tab edited meanwhile marks it changed-on-disk and stale instead of dropping the change. * chore(watcher): use a numeric markdown scan id * fix(watcher): don't let later events join a stale echo-verification read Payloads from the same burst still share the in-flight read; a payload from a later task gets exactly one fresh read issued after the current one settles.
35 lines
1.1 KiB
TypeScript
35 lines
1.1 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
|
import {
|
|
WATCH_BATCH_INTERVAL_MS,
|
|
WATCH_BATCH_LEADING_MS,
|
|
watchBatchFlushDelayMs
|
|
} from './filesystem-watch-batch-window'
|
|
|
|
describe('watchBatchFlushDelayMs', () => {
|
|
it('uses the leading delay before the first flush', () => {
|
|
expect(watchBatchFlushDelayMs(1_000_000, 0)).toBe(WATCH_BATCH_LEADING_MS)
|
|
})
|
|
|
|
it('uses the leading delay once a full interval has passed', () => {
|
|
expect(watchBatchFlushDelayMs(1_000 + WATCH_BATCH_INTERVAL_MS, 1_000)).toBe(
|
|
WATCH_BATCH_LEADING_MS
|
|
)
|
|
})
|
|
|
|
it('waits out the rest of the interval after a recent flush', () => {
|
|
expect(watchBatchFlushDelayMs(1_010, 1_000)).toBe(WATCH_BATCH_INTERVAL_MS - 10)
|
|
})
|
|
|
|
it('never returns less than the leading delay', () => {
|
|
expect(watchBatchFlushDelayMs(1_090, 1_000)).toBe(WATCH_BATCH_LEADING_MS)
|
|
})
|
|
|
|
it('never waits longer than one interval when the clock moves backwards', () => {
|
|
expect(watchBatchFlushDelayMs(1_000, 3_600_000)).toBe(WATCH_BATCH_INTERVAL_MS)
|
|
})
|
|
|
|
it('honours custom windows', () => {
|
|
expect(watchBatchFlushDelayMs(1_000, 950, 5, 200)).toBe(150)
|
|
})
|
|
})
|