Skip to content

fix(state-store): the switch to WAL is best effort wherever a native connection opens the store - #2024

Merged
Fmarzochi merged 1 commit into
mainfrom
fix/wal-switch-best-effort
Oct 24, 2026
Merged

Fmarzochi merged 1 commit into
mainfrom
fix/wal-switch-best-effort

Conversation

@Fmarzochi

Copy link
Copy Markdown
Owner

Why

Right after the v1.1.23 tag, the main run for d424ee6 went red in one lane (ubuntu-latest, Node 20, npm): tests/lib/state-store-concurrency.test.js, case test_mcp_server_style_concurrency_with_hook_writers, with SQLITE_BUSY: database is locked thrown by the process that simulates the memory server, while the same tree passed the other 22 lanes, the tag's own CI and the pull request's. The rerun passed; ten local runs passed. The shape is the one scripts/hooks/state-db-writer.js already documents for itself: PRAGMA journal_mode = WAL needs the file to itself and the busy handler does not always cover that step, so processes opening the same store at the same moment see SQLITE_BUSY at once. The hook writer retried; the memory server did not (memory-db.ts at start, memory-misc-tools.ts in detect_patterns), nor did the test's simulated server. On a saturated machine the real server's start could fail the same way.

What changes

  • scripts/lib/state-store/sqlite-compat.js: enableWalBestEffort(db) moves here from the hook writer, next to the engine chooser: twenty attempts fifty milliseconds apart on SQLITE_BUSY, then the mode is left to the next opener; any other error still surfaces; a store already in WAL is left alone.
  • scripts/hooks/state-db-writer.js: imports the helper instead of carrying its own copy. Same behavior.
  • mcp/servers/egc-memory/src/sqlite-compat.ts: exposes the helper through the typed door; memory-db.ts and memory-misc-tools.ts call it after busy_timeout instead of the bare pragma (the misc tool also sets the timeout before the switch now).
  • tests/lib/state-store-concurrency.test.js: the native writer of the mixed-engine case and the simulated server switch WAL through the helper.
  • tests/scripts/sqlite-compat.test.js: a new case with a fake connection pins the retry, the quiet give-up after twenty busy answers, the rethrow of another error and the untouched WAL store.
  • CHANGELOG.md and docs/ROADMAP.md: the entry (fix(state-store): the switch to WAL is best effort wherever a native connection opens the store #2024).

WAL is a performance setting, not a correctness one: every query still waits through busy_timeout whatever the journal mode.

Proof

  • node tests/scripts/sqlite-compat.test.js: 24 passed, 0 failed.
  • node tests/lib/state-store-concurrency.test.js: 17 passed, 0 failed (the simulated server case included, with the built memory server present).
  • node tests/hooks/state-db-writer.test.js: 5 passed.
  • npx tsc --noEmit -p mcp/servers/egc-memory: clean; the server rebuilt.
  • eslint clean on the changed JavaScript; no em or en dash in the changed files.

…connection opens the store

Signed-off-by: Felipe Marzochi <fmarzochi@gmail.com>
@sonarqubecloud

Copy link
Copy Markdown

@codecov

codecov Bot commented Oct 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Fmarzochi
Fmarzochi merged commit a28d3de into main Oct 24, 2026
36 checks passed
@Fmarzochi
Fmarzochi deleted the fix/wal-switch-best-effort branch October 24, 2026 18:04
@github-project-automation github-project-automation Bot moved this from Todo to Done in EGC Roadmap Oct 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant