Skip to content

refactor(negentropy): split negentropy build into read-only and write txn phases#220

Open
Thunder-Blaze wants to merge 1 commit into
hoytech:masterfrom
Thunder-Blaze:refactor/negentropy-split-txn-phases
Open

refactor(negentropy): split negentropy build into read-only and write txn phases#220
Thunder-Blaze wants to merge 1 commit into
hoytech:masterfrom
Thunder-Blaze:refactor/negentropy-split-txn-phases

Conversation

@Thunder-Blaze

Copy link
Copy Markdown
Contributor

Issue

  • FIXME at `src/apps/dbutils/cmd_negentropy.cpp:83

Description

The negentropy build subcommand currently opens a single read-write transaction (txn_rw()) that spans both the event scan and the BTree storage write. On large databases, the scan can take a long time — and during that entire window, all other writers (event ingestion, deletions, etc.) are blocked because LMDB only allows one writer at a time.

This splits the operation into two phases:

  1. Read-only phase (txn_ro()): fetch the filter and scan all matching events, collecting (created_at, id) pairs into a vector.
  2. Write phase (txn_rw()): increment the modification counter and insert the collected records into the BTree.

The write transaction is now held only for the short insertion step.

@theAnuragMishra

Copy link
Copy Markdown
Contributor

When I was working on writing a real time chess arena server in go, I faced this kind of situation with mutexes a lot. Whether to hold read and write locks separately or a combined lock for both read and write. Most of the time the latter came out to be the uncomfortable right choice. Because if you allow writers after reading and before writing, there are chances that the data from the read point goes stale before the write occurs.
Not sure how much this applies here though.

@Thunder-Blaze

Copy link
Copy Markdown
Contributor Author

yes I think you are right
If we got interference then what you told might happen
I think maybe I should try implementing a memory queue to hold off any events that are happening until we write and then apply those events after the writing has finished and then release the lock and empty the queue

This seemed like most optimal choice to me

@Thunder-Blaze

Thunder-Blaze commented Apr 23, 2026

Copy link
Copy Markdown
Contributor Author

I've looked into this in more detail since our last discussion, and I actually think the current approach in this PR works perfectly fine for this use case.

We have to remember that Negentropy's entire job is efficient set reconciliation. The protocol inherently expects state drift and is designed to heal it automatically. Even if the tree is slightly out of date during a given pass, it doesn't break anything. During the next sync cycle, the peer will naturally identify the delta (e.g., "Relay A has these 47 new events I'm missing") and fetch them.

@Thunder-Blaze Thunder-Blaze changed the title refactor(negentropy): split negentropy build into read-only and write… refactor(negentropy): split negentropy build into read-only and write txn phases May 15, 2026
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