Skip to content

perf(scheduler): resolve projectPath from cache_meta instead of re-reading JSONLs - #65

Merged
abasiri merged 1 commit into
doctly:mainfrom
devsuitup:contrib/scheduler-skip-jsonl-head-reads
Aug 1, 2026
Merged

perf(scheduler): resolve projectPath from cache_meta instead of re-reading JSONLs#65
abasiri merged 1 commit into
doctly:mainfrom
devsuitup:contrib/scheduler-skip-jsonl-head-reads

Conversation

@JeanBaptisteRenard

Copy link
Copy Markdown
Contributor

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's cwd (its projectPath). With many projects this is repeated disk I/O and JSON parsing every minute, even though the same mapping is already cached.

Fix

db.js already maintains a cache_meta table and exports getAllFolderMeta() returning a Map<folder, row> where each row carries projectPath. The scheduler now:

  • Builds a folder → projectPath map from cache_meta once per scan (loadFolderMetaMap()).
  • Resolves projectPath from that cache first.
  • Falls back to the existing JSONL head-read (readProjectPathFromJsonl()) only when a folder is genuinely uncached.

db.js is lazy-required inside the function so that requiring schedule-runner.js never forces the native better-sqlite3 binding to load, and the lookup is wrapped in try/catch returning an empty map if the cache is unavailable — falling back to the original behavior.

Notes

Behavior-preserving: identical projectPath resolution (same fallback, same if (!projectPath) continue, same schedules/triggers). No db.js changes were needed — the existing getAllFolderMeta() export is reused as-is. Syntax-checked (node --check); the test suite passes.

@abasiri
abasiri merged commit f92a6de into doctly:main Aug 1, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants