atomic-log
atomic-log is a Rust library for sharing a recent rolling window of values from one
writer to many readers with very little coordination.
It is built for in-process streaming workloads where readers care more about a stable, recent view than about guaranteed delivery of every historical update. The log is append-only, segmented, zero-copy on the read side, and uses atomics for publication.
At a glance
- Single writer, many readers
- Atomics-only publication and observation in the core path
- No reader registration
- Generic over
T - Fixed-size segmented storage
- Zero-copy snapshots backed by stable segment allocations
- Automatic reclamation of old segments
- Flat iteration and per-segment chunk iteration
When to use it
atomic-log is a good fit when:
- one thread publishes and many threads observe
- readers mainly care about the latest retained state
- stale history may be dropped
- readers should not block the writer
- zero-copy reads are valuable
- bounded retention matters more than full replay
Typical examples:
- market data
- telemetry
- service health and status propagation
- real-time monitoring
- replicated in-memory state views
When not to use it
Do not use atomic-log when:
- every message must be delivered
- readers must never miss an update
- commands or events must be processed exactly once
- multiple writers need to append concurrently without external synchronization
- data must survive restarts
For those cases, a channel, queue, or durable log is usually the right tool.
Model
The writer appends values into a fixed-capacity head segment. When that segment fills, a
new head segment is allocated and published. Readers build Snapshot<T> values from the
current head and iterate over immutable published prefixes of the retained segments.
Snapshots are stable:
- readers only observe fully published values
- published values are never mutated again
- holding a snapshot keeps its backing segments alive
- readers access
&Tdirectly from segment storage without copying
Refreshing a snapshot replaces it with a newer captured view. If a reader falls behind beyond the retained history, continuity across refreshes may be lost.
Retention semantics
The constructor takes:
retained_capacity: target logical retention in elementssegment_capacity: fixed elements per segment
The current implementation retains whole segments, not exact element counts, so the
visible live window is rounded to segment boundaries and may exceed retained_capacity.
That tradeoff keeps publication and reclamation simple while preserving stable zero-copy
snapshots.
Example
use AtomicLog;
let = new;
for value in 0..6
let mut snapshot = log.snapshot;
assert_eq!;
writer.append;
writer.append;
snapshot.refresh;
assert_eq!;
let chunks: = snapshot
.chunks
.map
.collect;
assert_eq!;
API summary
AtomicLog::new(retained_capacity, segment_capacity)creates a writer and read handleWriter::append(value)publishes one valueAtomicLog::snapshot()captures a stable read viewSnapshot::refresh()updates an existing snapshot in placeSnapshot::iter()yields&TSnapshot::chunks()yields per-segment slices plus sequence numbers
License
Licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.