refactor(negentropy): split negentropy build into read-only and write txn phases#220
Conversation
|
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. |
|
yes I think you are right This seemed like most optimal choice to me |
|
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. |
Issue
Description
The
negentropy buildsubcommand 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:
txn_ro()): fetch the filter and scan all matching events, collecting(created_at, id)pairs into a vector.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.