Repository navigation
fix(db): extract WAL maintenance, surface TRUNCATE no-op - #12853
Merged
diegosouzapw merged 1 commit intoSep 8, 2026
Merged
diegosouzapw merged 1 commit into
diegosouzapw merged 1 commit into
Conversation
maxmad64bis
force-pushed
the
fix/batch10-wal-maintenance
branch
3 times, most recently
from
September 6, 2026 12:02
564d0a6 to
b10f35d
Compare
maxmad64bis
force-pushed
the
fix/batch10-wal-maintenance
branch
from
September 6, 2026 15:07
b10f35d to
ef1bdbb
Compare
diegosouzapw
merged commit Sep 8, 2026
2959337
into
cheaper-inference:release/v3.8.51
8 of 16 checks passed
This was referenced Sep 8, 2026
Closed
5 tasks done
This was referenced Sep 15, 2026
Merged
diegosouzapw
added a commit
that referenced
this pull request
Sep 17, 2026
…-09-15) (#13731) Second `npm run release:reconcile` pass on `release/v3.8.50..release/v3.8.51` (0915890..c0f92ec, 916 non-merge commits, 877 merged PRs): - fold the 173 changelog.d fragments accumulated since #12971 under `## [3.8.51]` and delete them - generate bullets for the 58 cycle commits that had no fragment (4 features / 42 fixes / 12 maintenance), each with the merged PR link and `— thanks @author` - link 137 fragment bullets to the PR of the commit that added them and credit the author; two prefix/origin mismatches reviewed (#12945→#13392, #13001→#13379, both maintainer rebaselines of other people's PRs) - refresh "Release by the numbers" + Top-25 and regenerate the `### 🙌 Contributors` hall (112 external contributors + maintainer; every non-bot author of the 877 merged PRs present) - closed-PR credit audit for the window: nothing to add (#13215→#13361 and #13059→#13690 are still open, #12998 was independently fixed earlier by #12853); no human co-author trailers, no commits without a PR - resync the 58 i18n CHANGELOG mirrors Gates: check:changelog-integrity OK, check:docs-sync PASS.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…erence#12853) Validado numa worktree combinada com a onda de persistência desta leva sobre `release/v3.8.51`: check-file-size e check-changelog-integrity OK, typecheck:core limpo, check-api-typecheck OK (289, dentro da baseline), 70 testes focados no runner Node e 1 no vitest, todos verdes. "Um checkpoint que nunca olhou o próprio resultado" é o tipo de defeito que só aparece quando o WAL fica maior que o banco. Ler a linha de retorno do pragma e diferenciar busy de sucesso é a correção; o retry `PASSIVE` um minuto depois é o que evita esperar as 6 horas do próximo tick. Gostei da decisão de não persistir contador: streak em memória que zera no stop é o comportamento honesto para uma métrica de contenção. Os 11 casos cobrem as formas de retorno que o pragma pode assumir — sentinela `-1`, objeto pelado, `undefined`/`null`/`[]` — que é onde esse tipo de parsing costuma quebrar em silêncio.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…-09-15) (cheaper-inference#13731) Second `npm run release:reconcile` pass on `release/v3.8.50..release/v3.8.51` (104d4f8..d61b804, 916 non-merge commits, 877 merged PRs): - fold the 173 changelog.d fragments accumulated since cheaper-inference#12971 under `## [3.8.51]` and delete them - generate bullets for the 58 cycle commits that had no fragment (4 features / 42 fixes / 12 maintenance), each with the merged PR link and `— thanks @author` - link 137 fragment bullets to the PR of the commit that added them and credit the author; two prefix/origin mismatches reviewed (cheaper-inference#12945→cheaper-inference#13392, cheaper-inference#13001→cheaper-inference#13379, both maintainer rebaselines of other people's PRs) - refresh "Release by the numbers" + Top-25 and regenerate the `### 🙌 Contributors` hall (112 external contributors + maintainer; every non-bot author of the 877 merged PRs present) - closed-PR credit audit for the window: nothing to add (cheaper-inference#13215→cheaper-inference#13361 and cheaper-inference#13059→cheaper-inference#13690 are still open, cheaper-inference#12998 was independently fixed earlier by cheaper-inference#12853); no human co-author trailers, no commits without a PR - resync the 58 i18n CHANGELOG mirrors Gates: check:changelog-integrity OK, check:docs-sync PASS.
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.
Summary
A long-running server never closes its DB, so the only thing reclaiming the WAL file is the periodic
wal_checkpoint(TRUNCATE)— and until now that checkpoint never actually looked at its own result.checkpointDbignored the pragma return and always reported success, so a checkpoint that hit a busy database silently did nothing and the next try came 6 hours later. It's the kind of bug you only notice when the WAL file is suddenly bigger than the database itself.This moves the whole WAL lifecycle out of
core.tsintosrc/lib/db/walMaintenance.ts. The new module reads the checkpoint result row: a busy checkpoint now warns with its streak (... still busy (streak 3)) and schedules one lightweightPASSIVEretry a minute later (which moves pages without waiting on writers; shrinking stays the nextTRUNCATEtick's job). Closing-time checkpoints no longer print success on builds that never had a database file.core.tsjust calls in — about 50 lines lighter, no signature changes for operators.The busy totals also surface in the authenticated monitoring health payload (
walMaintenancekey: ticks, current streak, lifetime busy count, last busy/ok timestamps), so an operator watching contention over time doesn't have to grep logs. Deliberately no persisted counter: the streak lives in memory and resets on stop.Related Issues
Validation
npm run lintTests Added Or Updated
tests/unit/wal-maintenance.test.ts(new, 11 tests): busy/clean/sentinel--1/bare-object/undefined-null-[]parsing, pragma-throw never propagates, guarded ctx skips, interval parsing (default/garbage/0),__resetForTests, start silent under test gate,bun:sqlitecheckpoint shape (passes underbun test, skips under Node).tests/unit/db-wal-truncate-scheduler.test.ts(rewritten 5 wiring tests + 1 new close-table test): new anchors on./walMaintenanceimport,startWalMaintenance(db/stopWalMaintenance()/runCheckpointNow, env literal + 6h default + self-gate in the new module,streakBeforectx at close.tests/unit/observability-payloads.test.ts(+1 test):walMaintenanceallowlist projection — documented scalars pass, timer internals never leak, null state degrades to null.tests/unit/db-core-init.test.ts(14/14, incl.checkpointMode: nullpin),tests/unit/db/vacuum-scheduler.test.ts(11/11), combined WAL+vacuum single-process run (21/21, shared resetter coupling).Coverage Notes
src/lib/db/(walMaintenance.tsnew,core.tsrewired) plus an additive health key (observability.ts, health route). Covered by the newwal-maintenance.test.ts(every outcome branch: busy/clean/sentinel/bare-object/fail-open×3/throw/skipped) plus the rewritten scheduler wiring tests plus the new projection test. No coverage regression expected — new code ships with its tests in the same PR;core.tsonly loses deleted lines.Reviewer Notes
PASSIVEretry costs one extra cheap checkpoint per busy event max, never re-arms, never touches the WAL shrink path.walMaintenance.tsnever imports./core(cycle gate clean);clearDbHealthCheckScheduler()ordering incloseDbInstancepreserved so no timer leaks. Health addition is one additive key (walMaintenance), management-auth-gated like the rest of the payload — nothing existing moves.typecheck:coreclean, ESLint clean on changed files,check:cyclesOK,check:file-sizesilent,check:docs-countsdrift is pre-existing (169→170migrations, untouched).test:bun:db22/22.