Skip to content

perf(desktop): cut startup log-directory scans from six to four - #605

Open
simpleqt wants to merge 1 commit into
anywhere-labs:masterfrom
simpleqt:perf/log-sink-boot-directory-scans
Open

perf(desktop): cut startup log-directory scans from six to four#605
simpleqt wants to merge 1 commit into
anywhere-labs:masterfrom
simpleqt:perf/log-sink-boot-directory-scans

Conversation

@simpleqt

Copy link
Copy Markdown

Fixes the startup directory-scan part of #584.

What

Every LogFileSink startup walks the log directory via ownedFiles() (a full readdirSync plus one lstatSync per owned log). The boot sequence in main.ts (new LogFileSinkenforceDirectoryCap()purgeOlderThan(7)writeHeader()) used to trigger six such walks:

  1. constructor measureDirectoryBytes()
  2. enforceDirectoryCap() ownedFiles()
  3. purgeOlderThan ownedFiles()
  4. purgeOlderThan closing measureDirectoryBytes()
  5. first rollDateloadState(all)
  6. first rollDateloadState(error)

(#584 counted ~5; the per-channel loadState pair makes it six.)

Change

  • rollDate() fuses the two per-channel loadState scans into one ownedFiles() pass (resumeSegmentState helper keeps the per-entry matching logic byte-for-byte, including the equal-segment readdir-order tie behavior).
  • purgeOlderThan() tracks surviving bytes inside the deletion loop instead of re-measuring the directory afterwards; locked old files still count toward the total, matching what the previous re-scan would have produced.

Boot now scans four times, and each daily date rollover scans once instead of twice. The per-line appendFileSync is untouched — closing after every append is the deliberate crash-safety tradeoff already documented in the code.

Verification

  • vitest run tests/log-files.spec.ts — 15/15, including two new regression tests:
    • resumes rotation from pre-existing segments for both channels in one pass
    • keeps rotation resume correct across the exact startup cap → purge → writeHeader sequence while old files are removed
  • full workspace suite — 82 files, 812 passed / 4 skipped
  • tsc typecheck (all five tsconfigs) — clean
  • root gates (bilingual-docs, architecture, verify-layout) — green

Copilot AI lite review requested due to automatic review settings August 25, 2026 05:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Boot constructs LogFileSink, calls enforceDirectoryCap() and
purgeOlderThan(7), then writeHeader(); every ownedFiles() pass is a
full readdirSync plus one lstatSync per owned log. That sequence used
to walk the directory six times (constructor measure, cap, purge x2,
and rollDate's per-channel loadState x2), reported in anywhere-labs#584.

- rollDate(): fuse the two per-channel loadState scans into one
  ownedFiles() pass; per-entry matching logic is unchanged, including
  the equal-segment readdir-order tie behavior.
- purgeOlderThan(): track surviving bytes during the deletion loop
  instead of re-measuring the directory afterwards; locked old files
  still count, so the accounting matches the previous re-scan.

appendFileSync-per-line stays: closing after every append is the
deliberate crash-safety tradeoff noted in the code.

Boot now scans four times, and each daily date rollover scans once
instead of twice.

Fixes anywhere-labs#584 (startup directory-scan part; the per-line sync write is
intentional and left as is)

Verified: vitest tests/log-files.spec.ts 15/15 (two new regression
tests: dual-channel segment resume, and cap-then-purge boot sequence),
full workspace suite 812 passed / 4 skipped, tsc typecheck clean,
bilingual/architecture/layout gates green.
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