betex
Deterministic, event-sourced matching engine for exchange odds and binary prediction markets.
WAL Locking
Mutable WAL opens take a fail-fast single-writer lock on WAL_ROOT/.writer.lock.
This prevents two writer processes from accidentally opening the same WAL root at the same time.
The lock is held for the lifetime of the mutable journal handler and is released automatically
when the process exits. Read-only recovery via JournalReader does not take the writer lock.
This locking model is intended for local filesystems and single-attach block storage, including
typical Kubernetes deployments backed by ReadWriteOnce / ReadWriteOncePod persistent disks.
It is not a complete fencing solution for shared RWX storage such as GKE Filestore, NFS, SMB, or other multi-node shared-disk environments. Those deployments need an external lease or fencing mechanism in addition to any local file lock.
WAL Sizing
JournalConfig.max_segment_events is a soft rotation hint, not a hard cap. The WAL poller commits
the full poll_wait() batch and only rotates after that commit on a tx boundary. In practice, the
true commit boundary is the available Disruptor backlog, bounded by ring size.
- Default live ring size is
32768. - Default
max_segment_eventsis5000, so the nominal target is about5000events/segment. - At roughly
500kevents/sec,5000events is about10msof traffic. - In live runs, Betex event payloads have been much smaller than the configured LMDB map:
observed segments were typically a few MiB, with the largest seen around
6.6 MiB.
Sizing example for the current largest known batched-cancel payload:
OrderCancelledBatchedwith4096cancelled orders serializes to about32904bytes.5000 * 32904 ~= 157 MiBraw payload.32768 * 32904 ~= 1.004 GiBraw payload for one full-ringpoll_wait()commit.
Operational implication:
- If
poll_wait()remains the effective commit boundary, sizesegment_map_size_bytesagainst the largest expected poll batch, not just againstmax_segment_events. max_segment_eventsshould be treated as a rotation hint for typical workloads, not as a strict upper bound on segment occupancy.