Coordination primitives
The largest group in the subetha-cxc crate. Primitives whose
shape is not a single coordination pattern (mutex, queue, map)
but a distributed-systems-style protocol: liveness, fan-out,
ordering, scheduling. Each is a piece of the coordination
substrate that an MMF-backed multi-process service composes
from.
Liveness
HeartbeatTable
Per-process liveness slots in a shared table. Each process periodically writes its current heartbeat-epoch into its slot; observers read the slot to detect whether a process is alive.
pub fn create(path: impl AsRef<Path>, capacity: usize) -> Result<Self, HeartbeatError>;
pub fn open(path: impl AsRef<Path>, expected_capacity: usize) -> Result<Self, HeartbeatError>;
pub fn register(&self, pid: u32) -> Result<usize, HeartbeatError>; // claim a slot
pub fn beat(&self, idx: usize); // write this slot's epoch
pub fn snapshot(&self, idx: usize) -> Option<HeartbeatSnapshot>; // read one slot
pub fn tick_global_epoch(&self) -> u64;IN_FLIGHT_SLOTS caps the simultaneous registered processes.
Op kinds use the liveness module: OP_BEAT = 1,
OP_REGISTER = 2, OP_WAIT = 3, OP_TICK_EPOCH = 4,
OP_SCAN = 5.
Canonical doc: HEARTBEAT.md .
FailoverWatchdog
The detection side of the heartbeat shape. Watches a
HeartbeatTable and reports which slots have gone stale;
reclaims work-in-progress that belonged to a dead process by
moving it to a healthy process’s slot.
pub fn create(
path: impl AsRef<Path>,
heartbeat_path: impl AsRef<Path>,
) -> Result<Self, /* ... */>;
pub fn scan(&self) -> Result<ReclaimReport, /* ... */>;DEFAULT_GRACE_EPOCHS is the default staleness threshold. The
reclaim is a one-shot move; the watchdog does not run as a
separate thread - the application calls scan on its own
cadence.
Canonical doc: FAILOVER.md .
EpochBarrier
Synchronisation barrier across processes. Each participant
calls wait(epoch) and blocks until all other participants have
also called wait(epoch). When the count reaches the registered
participant count, the barrier releases and the epoch advances.
pub fn create(path: impl AsRef<Path>, capacity: usize) -> Result<Self, BarrierError>;
pub fn open(path: impl AsRef<Path>, expected_capacity: usize) -> Result<Self, BarrierError>;
pub fn wait(&self, my_epoch: u32) -> Result<(), BarrierError>;
pub fn wait_quorum(&self, my_epoch: u32, quorum: u32) -> Result<(), BarrierError>;
pub fn live_peer_count(&self) -> u32;
pub fn current_epoch(&self) -> u32;DEFAULT_BARRIER_GRACE_EPOCHS is the grace period after which
a non-responding participant is dropped. Useful for
phased-execution patterns where every participant has to finish
phase N before any starts phase N+1.
Canonical doc: EPOCH_BARRIER.md .
Event log
EventStateLog
Append-only event log with fold semantics over two concrete type
parameters, Event and State. Producers call emit(event);
drain_and_fold(|state, event| ...) consumes the pending events and
folds them into the log’s materialized State, which read_current
returns.
// EventStateLog<Event: Copy + 'static, State: Copy + 'static>
pub fn create(path: impl AsRef<Path>, capacity: usize) -> Result<Self, EventLogError>;
pub fn emit(&self, event: Event) -> Result<(), EventLogError>;
pub fn drain_and_fold<F: FnMut(&mut State, &Event)>(&self, fold: F) -> usize; // events folded
pub fn read_current(&self) -> State;
pub fn set_state(&self, state: State);The shape matches CQRS read-side projections: events are the source of truth; each observer projects its own state.
Op kinds use the event_log module: OP_EMIT = 1,
OP_DRAIN_FOLD = 2, OP_READ_CURRENT = 3.
Canonical doc: EVENT_STATE_LOG.md .
SharedVersionedChain
Append-only versioned history. Each push adds a new node with
an incremented version; readers can read the value at any past
version via read_at.
Used for time-travel debugging, snapshot isolation, and audit
trails across processes. Op kinds use the versioned module:
OP_PUSH = 1, OP_READ_AT = 2, OP_CURRENT = 3,
OP_VISIBLE_MASK = 4.
Canonical doc: SHARED_VERSIONED_CHAIN.md .
SharedTimePointTile
Time-keyed snapshot slots. Each slot records the value at a specific time point; lookup returns the value as-of that time. Used for time-series sampling where the exact sample times are known in advance.
TILE_CAP caps the simultaneous time-point slots. Op kinds use
the versioned module.
Canonical doc: SHARED_TIME_POINT.md .
Fan-out and scheduling
PriorityFanout
Multi-priority work distribution. Producers submit work units
with a priority level (0 to MAX_PRIORITIES - 1); consumers
drain by descending priority. Used for QoS-aware work
distribution where high-priority work must overtake
low-priority work in flight.
Op kinds use the priority_fanout module: OP_SUBMIT = 1,
OP_DRAIN_HIGHEST = 2, OP_DRAIN_PRIORITY = 3.
Canonical doc: PRIORITY_FANOUT.md .
ProgressTask
Long-running task progress tracker. The worker calls advance(n)
to report progress; observers call read to see the current
progress without blocking the worker; complete marks the task
finished.
Op kinds use the progress module: OP_ADVANCE = 1,
OP_READ = 2, OP_COMPLETE = 3.
Canonical doc: PROGRESS_TASK.md .
BackgroundScheduler
Job scheduler with submitter and collector roles. Producers
submit Submitter-typed jobs; the scheduler dispatches them to
workers; results are collected by ResultCollector. The whole
thing is one MMF region so the producers, the scheduler, and the
collectors can be in different processes.
Op kinds use the scheduler module: OP_SUBMIT = 1,
OP_RECV = 2, OP_WATCHDOG_SCAN = 3.
Canonical doc: SCHEDULER.md .
Graph and topology
SharedGraph
Cross-process graph with add_node, add_edge, neighbors,
remove_edge operations. Nodes and edges are inline (fixed
payload size); links use OffsetPtr so the layout works
two-process.
Op kinds use the graph module: OP_ADD_NODE = 1,
OP_ADD_EDGE = 2, OP_NEIGHBORS = 3, OP_REMOVE_EDGE = 4.
Canonical doc: SHARED_GRAPH.md .
SharedTopologyMap
Routing topology and fan-in / fan-out recommendations. Records observed connection patterns; queries return a routing recommendation based on historical data. Used by adaptive routers that switch between fan-out and fan-in modes based on observed downstream load.
Op kinds use the topology module: OP_RECORD = 1,
OP_FAN_OUT = 2, OP_FAN_IN = 3, OP_RECOMMEND = 4.
Canonical doc: SHARED_TOPOLOGY_MAP.md .
Other coordination shapes
KTowerCascade
K-level resolver cascade. Lookups walk through K resolver levels in sequence; the first level to return a hit short- circuits the rest. Used for layered cache hierarchies (memory to MMF to disk) where each level has different cost and hit rate characteristics.
Op kinds use the cascade module: OP_INSERT = 1,
OP_GET = 2.
Canonical doc: K_TOWER_CASCADE.md .
SharedAsyncPointer
Async lazy resolution. The first caller’s
get_or_fetch(fetch_fn) triggers the fetch; subsequent callers
either wait for the in-flight fetch or read the resolved value.
Cross-process variant of the in-memory OnceLock<T> shape, with
async fetch semantics.
Op kinds use the async_pointer module: OP_GET_OR_FETCH = 1,
OP_TRY_GET = 2.
Canonical doc: SHARED_ASYNC_POINTER.md .
SharedUniversal
A generic strategy-adaptive store. Inserts / contains_key /
remove plus an explicit migrate op that changes the internal
representation. Used when the application wants the
strategy-adaptation hook the adaptive primitives have, but for
data that lives across processes.
Op kinds use the universal module: OP_INSERT = 1,
OP_CONTAINS = 2, OP_REMOVE = 3, OP_MIGRATE = 4.
Canonical doc: SHARED_UNIVERSAL.md .
SharedNaNValue and SharedNaNTaggedValue
NaN-boxing for cross-process polymorphism. Stores i32, u32,
bool, or pointer values inside the bit pattern of an IEEE-754
double NaN, using the unused mantissa bits. The TAG_*
constants identify the contained type; the canonical QNAN bit
pattern is the discriminator.
Used in dynamic languages and JIT runtimes where every value has the same wire size and the type is discriminated inline. The cross-process variant lets two processes exchange typed values without an out-of-band type channel.
Canonical docs: SHARED_NAN_VALUE.md , SHARED_NAN_TAGGED_VALUE.md .
SharedUmbraPointer
Cross-process variant of the Umbra inline-prefix pointer (16 B prefix inline, fallback to OffsetPtr beyond). The prefix compare lets equality and prefix queries short-circuit without deref; the full value is reached via the offset pointer.
Op kinds use the umbra_pointer module: OP_PREFIX_EQ = 1,
OP_RESOLVE = 2.
Canonical doc: SHARED_UMBRA_POINTER.md .
Vec and linked list
SharedVec<T> and SharedLinkedList<T> round out the
collection shapes. The vec is indexed access with OP_PUSH,
OP_POP, OP_GET, OP_SET, OP_LEN, OP_CLONE; the linked
list adds both-end ops via OP_PUSH_HEAD, OP_PUSH_TAIL,
OP_POP_HEAD, OP_POP_TAIL.
Canonical docs: SHARED_VEC.md , SHARED_LINKED_LIST.md .
SharedRegion
Sub-allocator inside an MMF. Application code allocates and frees variable-size chunks inside the region; the region tracks free space via a free-list. Used as the backing for primitives that need variable-size payloads but want them all inside one MMF.
Op kinds use the region module: OP_ALLOCATE = 1,
OP_FREE = 2, OP_GET = 3, OP_SET = 4.
Canonical doc: SHARED_REGION.md .
pass_registry
Cross-process closure registry, a process-global module rather
than a type: register(id, f) / unregister(id) /
is_registered(id) / registered_count() / execute(&Pass).
An application registers handlers by Pass id; a remote process
sends the id and its argument bytes, and the handler runs in
whichever process registered it. The function pointers never
leave the registering process’s address space.
Used to coordinate cross-process dispatch when the work runs in a specific process (because of resource ownership, security context, or hardware affinity) but the request can come from any process. Canonical doc: PASS_REGISTRY.md .
See also
- Ownership primitives
-
OwnerLease/SharedLeaderElection/LazyConfigfor resource ownership. - Architecture - where these coordination primitives sit in the stack.
- Role-pair selection - the liveness, owner/lease, event/observer, and submitter/ scheduler shapes the coordination primitives fit.