perf(scheduler): resolve projectPath from cache_meta instead of re-reading JSONLs - #65
Merged
abasiri merged 1 commit intoAug 1, 2026
Conversation
abasiri
added a commit
to joeytwiddle/switchboard
that referenced
this pull request
Aug 1, 2026
Brings the branch up to date with main (28 commits behind). One conflict, in the open-terminal handler: main gained `if (isNew && sessionOptions.worktree)` (the worktree-on-resume fix, 10b80e2) while this branch rewrote the same block from string concatenation to an argv array. Resolved by keeping both — the isNew gate on the argv push — since taking either side alone would silently drop one of the two fixes. schedule-runner.js and schedule-ipc.js auto-merged cleanly with doctly#65, which changed scanSchedules while this branch changes buildScheduleCommand. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
abasiri
added a commit
to Davidb-2107/switchboard
that referenced
this pull request
Aug 1, 2026
…e test Branch was 14 behind. Two things needed fixing, both merge-order artifacts — doctly#60 and doctly#65 landed after this branch was written. schedule-runner.js conflicted, but the two changes compose rather than compete. doctly#65 made scanSchedules prefer a cache_meta folder→projectPath lookup, falling back to reading a JSONL head only for folders missing from the cache; this branch made that head read cheap. Resolved by keeping doctly#65's structure and putting readHead(…, 4096) inside its readProjectPathFromJsonl fallback, so the common path does no file read at all and the fallback no longer loads a possibly-hundreds-of-MB file to look at its first line. test/reconcile-cache.test.js failed because refreshFolder now fetches the cached row to use as resume state, and that test's fake db predates the method: ✖ reconcileCacheFromFilesystem indexes new and stale folders … getCachedSession → undefined Added getCachedSession() { return null; } to the fake, modelling a session with nothing indexed yet. Fixed in the fake rather than guarding the call site: the real db provides the method, and a guard would mask genuine wiring errors. 27/27 tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Problem
On every 60s scheduler tick,
scanSchedules()re-reads the first 4KB of every project's JSONL files (fs.readFileSync(jsonl, 'utf8').slice(0, 4000)) for every project folder, solely to extract each project'scwd(itsprojectPath). With many projects this is repeated disk I/O and JSON parsing every minute, even though the same mapping is already cached.Fix
db.jsalready maintains acache_metatable and exportsgetAllFolderMeta()returning aMap<folder, row>where each row carriesprojectPath. The scheduler now:folder → projectPathmap fromcache_metaonce per scan (loadFolderMetaMap()).projectPathfrom that cache first.readProjectPathFromJsonl()) only when a folder is genuinely uncached.db.jsis lazy-required inside the function so that requiringschedule-runner.jsnever forces the nativebetter-sqlite3binding to load, and the lookup is wrapped intry/catchreturning an empty map if the cache is unavailable — falling back to the original behavior.Notes
Behavior-preserving: identical
projectPathresolution (same fallback, sameif (!projectPath) continue, same schedules/triggers). Nodb.jschanges were needed — the existinggetAllFolderMeta()export is reused as-is. Syntax-checked (node --check); the test suite passes.