Skip to content

fix: make session shard export deterministic - #5

Open
aquelejota wants to merge 1 commit into
doomsday616:mainfrom
aquelejota:fix/deterministic-export
Open

aquelejota wants to merge 1 commit into
doomsday616:mainfrom
aquelejota:fix/deterministic-export

Conversation

@aquelejota

Copy link
Copy Markdown

Fixes #3.

buildShard() wrote exportedAt: Date.now() into every shard, so an unchanged session produced new bytes on every export. Git flagged every shard as modified, and with autoPushOnIdle each idle created a commit touching every session file. Measured on a real two-machine setup with ~912 shards: every push and every startup pull carried all 912 files.

After deriving the timestamp from the session itself, a no-change export is byte-identical and the next push contains only genuinely changed sessions (2 files in our test, the sessions actually in use).

Two changes:

  1. exportedAt now comes from session.time_updated (src/core/sessions.ts), so a repeat export of an unchanged session is deterministic. Existing shards are rewritten once (the field value changes); after that the export is stable. The field is informational only — import reads shard.session.time_updated, not exportedAt — so there is no compatibility concern.

  2. The regression test for this already existed but never ran: under vitest the dynamic import("node:sqlite") fails to resolve ("Failed to load url sqlite"), sqliteAvailable() returned false, and every session test returned early via if (!available) return. src/core/sqlite.ts now falls back to createRequire to load the builtin, so the session tests actually execute.

Verification:

  • npx vitest run tests/sessions.test.ts — 12 passed; the suite went from ~15ms (all early returns) to ~82ms with the database actually exercised.
  • Reverting only the exportedAt line makes writes byte-identical shards on a repeat export fail with different bytes, so the test now guards the behavior.

exportedAt used Date.now(), so the shard payload changed on every export
even when the session itself did not. git saw every shard as modified and
autoPushOnIdle produced a commit touching every session file on each idle.

Derive exportedAt from the session's own time_updated instead, so a repeat
export of an unchanged session is byte-identical and pushes stay incremental.

The existing regression test never caught this: under vitest the dynamic
import("node:sqlite") fails to resolve, sqliteAvailable() reported false
and every session test returned early. Fall back to createRequire so the
builtin loads under test runners and the session tests actually execute.

Refs doomsday616#3
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.

Session shards are rewritten on every export because exportedAt uses Date.now()

1 participant