Every edge in a Lattice graph is a bounded ring buffer with a fixed single-producer/single-consumer (SPSC) or multi-producer/single-consumer (MPSC) shape. There is no unbounded queue option by design.
- Capacity must be a power of two; graph build fails with
GraphBuildExceptionif it is not. MPSC capacity must be at least2. - The compiler may remove physical buffers for eligible fused internal edges, and may remove the source ingress edge for eligible source-inline elision.
- Capacity is per-edge. There is no global queue domain.
- Single producer thread, single consumer thread, statically known.
- Plain-claim publication, release/acquire ordering on
tail/head. - Producer cursor and consumer cursor live in cache-line-padded boxes
(
PaddedLongCache) so they do not false-share. - The producer owns
tail; the consumer ownshead. Control-plane close does not mutate producer-owned SPSC cursors. - Closing an SPSC edge is a one-way transition via a separate close flag. The
fastest
SourceMode.SINGLE_PRODUCERcontract requires close/stop/abort not to race active applicationemit(...)calls.
- Many producer threads, single consumer thread.
- CAS on
tailto reserve, plain claim into the slot, release publication. - The consumer's read of its local
headcursor uses opaque ordering; the acquire load is on the producer-published sequence. - Reservation order, not wall-clock order, defines downstream order.
- POJO payloads are user-owned references. Lattice does not copy.
- Slab handles (
SlabHandle<T>) are reference-counted, single-owner payloads issued by aSlabPool. Acquire on the producer side, release at the terminal sink (or each branch of a broadcast). The compiler validates retain/release pairing for the topologies it accepts; it rejects unsupported reuse shapes at build time.
The producer side observes capacity. When the ring is full, the configured
OverflowPolicy decides what happens: block, time-bounded
block, fail-fast, drop-latest, drop-oldest, coalesce, or redirect.
- Closing a source drains accepted items already in flight.
abort()closes all edges first, interrupts workers, awaits termination, then drains any remaining items. If workers do not terminate, cleanup is left to the final worker-stop path rather than racing a live consumer.- A closed edge releases any outstanding slab handles when it is drained.