Skip to content

Ingest a batch of events in one transaction - #120

Merged
sepehr-safari merged 2 commits into
mainfrom
ingest-a-batch-in-one-transaction
Sep 23, 2026
Merged

sepehr-safari merged 2 commits into
mainfrom
ingest-a-batch-in-one-transaction

Conversation

@sepehr-safari

Copy link
Copy Markdown
Contributor

Closes #119.

Store.ingestBatch is ingest for many events in one write transaction. Every event gets exactly the treatment ingest gives it, in order, and sees what the events before it in the batch wrote: a deletion earlier in a batch tombstones an event later in it, and a newer replaceable event supersedes an older one. One transaction is one commit, and LMDB syncs on every commit, so a batch costs one sync where one-at-a-time ingest cost one per event.

ingest is now ingestBatch of one event, so the logic exists once. The tombstone check, deletion and replaceable upsert take the caller's transaction instead of opening their own; the tombstone check now reads inside the write transaction, which is what lets a batch see its own deletions.

Tests

  • All existing ingest tests pass unchanged, which is the check that its outcomes did not move.
  • a batch sees what the events before it in the batch wrote: a deletion before its target, an older then newer then older profile, and a duplicate, in one batch.
  • a batch gives every event the outcome ingest would, one at a time: the same mixed sequence (a foreign deletion, parameterized replaceables out of order, an ephemeral event, a repeat) through both paths, compared result by result and by event count.

With the tombstone check removed, three tests fail, including the batch one. All 214 tests pass.

Release

The last commit bumps the version to 0.14.6.

Store.ingestBatch gives each event exactly the treatment ingest gives it, in order, inside one write transaction, and each event sees what the ones before it in the batch wrote. ingest opened and committed a transaction per event, and LMDB syncs on every commit, so a client storing events as they arrived paid a sync per event.

ingest is now ingestBatch of one event, so there is one copy of the logic. The helpers it used (tombstone check, deletion, replaceable upsert) take the caller's transaction instead of opening their own.

Closes #119.
Carries Store.ingestBatch.
@sepehr-safari
sepehr-safari merged commit de3db6b into main Sep 23, 2026
2 checks passed
@sepehr-safari
sepehr-safari deleted the ingest-a-batch-in-one-transaction branch September 23, 2026 14:20
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.

Ingesting events one at a time costs a disk sync each

1 participant