Expand description
§rusteron-archive
rusteron-archive is a module within the rusteron project that provides functionality for interacting with Aeron’s archive system in a Rust environment. This module builds on rusteron-client, adding support for recording, managing, and replaying archived streams.
§Sponsored by GSR
Rusteron is proudly sponsored and maintained by GSR, a global leader in algorithmic trading and market making in digital assets.
It powers mission-critical infrastructure in GSR’s real-time trading stack and is now developed under the official GSR GitHub organization as part of our commitment to open-source excellence and community collaboration.
We welcome contributions, feedback, and discussions. If you’re interested in integrating or contributing, please open an issue or reach out directly.
§Overview
The rusteron-archive module enables Rust developers to leverage Aeron’s archive functionality, including recording and replaying messages with minimal friction.
For MacOS users, the easiest way to get started is by using the static library with precompiled C dependencies. This avoids the need for cmake or Java:
rusteron-archive = { version = "0.2", features = ["static", "precompile"] }If you prefer a rustls-only downloader dependency:
rusteron-archive = { version = "0.2", features = ["static", "precompile-rustls"] }§Installation
Add rusteron-archive to your Cargo.toml depending on your setup:
# Dynamic linking (default)
rusteron-archive = "0.2"
# Static linking
rusteron-archive = { version = "0.2", features = ["static"] }
# Static linking with precompiled C libraries (best for Mac users, no Java/cmake needed)
rusteron-archive = { version = "0.2", features = ["static", "precompile"] }
# Static linking with precompiled C libraries using rustls downloader
rusteron-archive = { version = "0.2", features = ["static", "precompile-rustls"] }When using the default dynamic configuration, you must ensure Aeron C libraries are available at runtime. The static option embeds them automatically into the binary.
§Development
Build tasks use just. Run just to list commands, or cargo install just if needed.
§Features
- Stream Recording – Record Aeron streams for replay or archival.
- Replay Handling – Replay previously recorded messages.
- Persistent Subscriptions – Replay recorded history, then seamlessly join the live stream (Aeron Archive 1.51.0). See below.
- Publication/Subscription – Publish to and subscribe from Aeron channels.
- Callbacks – Receive events such as new publications, subscriptions, and errors.
- Automatic Resource Management (via
new()only) – Constructors automatically call*_initand clean up with*_closeor*_destroywhen dropped. - String Handling –
new()and setter methods accept&CStr; getter methods return&str.
§General Patterns
§Cloneable Wrappers
All wrapper types in rusteron-archive implement Clone and share the same underlying Aeron C resource. For shallow copies of raw structs, use .clone_struct().
§Mutable and Immutable APIs
Most methods use &self, allowing mutation without full ownership transfer.
§Resource Management Caveats
Automatic cleanup applies only to new() constructors. Other methods (e.g. set_aeron()) require manual lifetime and validity tracking to prevent resource misuse.
§Handlers and errors
Retained-callback setters take the callback by value (a closure or trait impl), keep it
alive inside the registering resource, and return the Handler for optional state access.
For synchronous polling, pass a stack closure:
// retained (e.g. an error handler on the archive context)
archive_context.set_error_handler(Some(|code: i32, msg: &str| eprintln!("archive error {code}: {msg}")))?;
// synchronous poll — note the fragment-limit argument
subscription.poll_fn(|buf: &[u8], header: AeronHeader| println!("{} bytes", buf.len()), 10)?;Handlers::NONE fits any optional callback slot.
For comprehensive details on how handler registration, callbacks, error checking, and idle strategies work in the rusteron ecosystem (which are fully applicable here as well), please refer to the corresponding sections in the rusteron-client documentation:
- rusteron-client: Handlers and Callbacks
- rusteron-client: Errors & Offer Results
- rusteron-client: Idle Strategies
Archive control operations (begin_replay, start_recording, …) return
Result<_, AeronArchiveError> — a typed code (AeronArchiveErrorCode) plus the archive’s
message. Constructors, async-connect, and context setters return AeronCError;
From<AeronArchiveError> for AeronCError keeps ? working across both.
§Documentation & Guides
For detailed guides and code snippets on Aeron features in Rust, see:
§Safety Considerations
- Aeron Lifetime – The
AeronArchivedepends on an externalAeroninstance. EnsureAeronoutlives all references to the archive. - Unsafe Bindings – The module interfaces directly with Aeron’s C API. Improper resource handling can cause undefined behavior.
- Automatic Handler Cleanup – Handlers are reference-counted; registered callbacks live as long as the resource that registered them and are freed automatically.
- Thread Safety – Use care when accessing Aeron objects across threads. Synchronize access appropriately.
§Typical Workflow
- Initialize client and archive contexts.
- Start Recording a specific channel and stream.
- Publish Messages to the stream.
- Stop Recording once complete.
- Locate the Recording using archive queries.
- Replay Setup: Configure replay target/channel.
- Subscribe and Receive replayed messages.
§Persistent Subscriptions
A persistent subscription replays a recording from a start position, then seamlessly merges into the live stream — so a consumer catches up on history without missing new messages and without a gap at the handover. Introduced in Aeron Archive 1.51.0.
- What it is: Aeron — Persistent Subscriptions (replay-to-live)
- How it works: Aeron Wiki — Persistent Subscriptions
- Background on publications/subscriptions: Aeron docs
Rusteron exposes it via persistent_subscription_builder() and the PersistentSubscriptionListener trait — a 1:1 wrapper over the Aeron C API (aeron_archive_persistent_subscription_*), mirroring Aeron’s PersistentSubscription.Context field-for-field.
use rusteron_archive::*;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
// `archive` is a connected AeronArchive; record + publish history first, then resolve recording_id.
let live_channel = "aeron:ipc";
let stream_id = 1001;
struct MyListener { live_joined: Arc<AtomicUsize> }
impl PersistentSubscriptionListener for MyListener {
fn on_live_joined(&self) { self.live_joined.fetch_add(1, Ordering::SeqCst); }
fn on_live_left(&self) { /* fell back to replay */ }
fn on_error(&self, code: i32, msg: &str) { eprintln!("ps error {code}: {msg}"); }
}
let live_joined = Arc::new(AtomicUsize::new(0));
let ps = persistent_subscription_builder()?
.aeron(&aeron)?
.archive_context(&archive_context)?
.live_channel(live_channel)? // the live stream to join
.live_stream_id(stream_id)?
.replay_channel("aeron:udp?endpoint=localhost:0")? // scratch channel for the replay
.replay_stream_id(stream_id + 1)?
.start_from_beginning()? // replay from the start (or .start_from_live())
.recording_id(recording_id)? // which recording to replay
.listener(MyListener { live_joined: live_joined.clone() })?
.build()?;
// Drive it: replay runs, then it joins live. `ps.poll_fn()` drives the archive
// client internally, so no `archive.poll_for_recording_signals()` is needed. Check
// `has_failed()` each iteration (terminal failure) and stop once `is_live()`.
while !ps.is_live() {
if ps.has_failed() {
panic!("persistent subscription failed: {:?}", ps.get_failure_reason());
}
let _ = publication.offer_with_reserved_value(b"live", Handlers::NONE);
ps.poll_fn(|buf, _hdr| { /* an assembled replayed or live message */ }, 100)?;
}
ps.close()?;Polling & errors. ps.poll_fn() drives the PS state machine and the archive async client, so you do not call archive.poll_for_recording_signals() separately. Loop on ps.is_live(), checking ps.has_failed() each iteration (reason via get_failure_reason()). The listener’s on_error covers non-terminal errors; on_live_left/on_live_joined may fire repeatedly as it falls back and rejoins.
Fragment assembly (already done for you). Unlike AeronSubscription, the persistent subscription reassembles fragments internally — the C aeron_archive_persistent_subscription_poll routes each image through aeron_image_fragment_assembler_handler, so your handler receives whole messages directly. Just poll:
loop {
// handler receives whole messages; no assembler needed
ps.poll_fn(|buf, _hdr| { /* handle reassembled message */ }, 100)?;
}If you prefer the shared assembler API (e.g. to reuse a collector across subscription types), AeronFragmentClosureAssembler works too — it polls the PS internally, so it advances the state machine and delivers messages in one call. Do not also call ps.poll_fn(…) separately: that consumes the messages before the assembler sees them.
let mut assembler = AeronFragmentClosureAssembler::new()?;
let mut ctx = Collector::default();
loop {
assembler.poll(&ps, &mut ctx, Collector::on_msg, 100)?; // polls the PS internally
if ctx.done { break; }
}For a fully runnable version, see the example and integration tests:
examples/persistent_subscription.rs— standalone demo (run withcargo run --release --features "static precompile" --example persistent_subscription)examples/archive_error_handling.rs— error handlers on both contexts, recording signals, typed control-session errors viaarchive.poll_for_error()/AeronArchiveError::parse(the archive’serrorCode=Nrecovered from the message text), and detecting/reconnecting after the archive goes downexamples/persistent_subscription_failover.rs— failure modes: live stream dies → automatic fallback to replay (on_live_left), then rejoins live when it returnsexamples/replay_merge.rs— late-joiner catch-up: replay recorded history, then merge seamlessly onto the live MDC stream (AeronArchiveReplayMerge)examples/recording_throughput.rs— recording throughput measurement (publish rate vs archiver catch-up) andlist_recordingsdescriptor enumerationexamples/recording_replication.rs— archive-to-archive replication (archive.replicate): a destination archive pulls a finished recording from a source archive and the copy is verified (port ofRecordingReplicator)persistent_subscription_tests::test_persistent_subscription_listener_live_joined(callback wiring)persistent_subscription_integration::test_end_to_end_persistent_subscription(record → replay → live)
§Benchmarks
For latency and throughput benchmarks, refer to BENCHMARKS.md.
§Contributing
Contributions are more than welcome! Please:
- Submit bug reports, ideas, or improvements via GitHub Issues
- Propose changes via pull requests
- Read our CONTRIBUTING.md
We’re especially looking for help with:
- API design reviews
- Safety and idiomatic improvements
- Dockerized and deployment examples
§License
Licensed under either MIT License or Apache License 2.0 at your option.
§Acknowledgments
Special thanks to:
- @mimran1980, a core low-latency developer at GSR and the original creator of Rusteron - your work made this possible!
- @bspeice for the original
libaeron-sys - The Aeron community for open protocol excellence
§Features
static: When enabled, this feature statically links the Aeron C code. By default, the library uses dynamic linking to the Aeron C libraries.backtrace: When enabled will log a backtrace for each AeronCErrorextra-logging: When enabled will log when resource is created and destroyed. Useful if you’re seeing a segfault due to a resource being closedlog-c-bindings: When enabled will log every C binding call with arguments and return values. Useful for debugging FFI interactionsprecompile: When enabled will use precompiled C code instead of requiring cmake and java to be installed
Modules§
Macros§
- cformat
format!for C strings: builds the formattedStringand converts it to aCStringin one visibly-named step.- skip_
unless_ java - Place at the top of any test that needs the Java archive. Skips the test
(early-returns
Ok(())) whenjavais not onPATH. Requires the test to return aResult<(), _>.
Structs§
- Aeron
- Aeron
Agent Close Func Logger - Aeron
Agent DoWork Func Logger - Aeron
Agent Runner - Aeron
Agent Start Func Logger - Aeron
Archive - Aeron
Archive Async Connect - Aeron
Archive Context - Aeron
Archive Control Response Poller - Aeron
Archive Credentials Challenge Supplier Func Logger - Aeron
Archive Credentials Encoded Credentials Supplier Func Logger - Aeron
Archive Credentials Free Func Logger - Aeron
Archive Delegating Invoker Func Logger - Aeron
Archive Encoded Credentials - Aeron
Archive Error - A typed archive control-session error: the
AeronArchiveErrorCodeplus the full message from the archive. - Aeron
Archive Persistent Subscription - Aeron
Archive Persistent Subscription Context - Aeron
Archive Persistent Subscription Listener - Listener for events from a persistent subscription.
- Aeron
Archive Proxy - Aeron
Archive Recording Descriptor - Struct containing the details of a recording
- Aeron
Archive Recording Descriptor Consumer Func Logger - Aeron
Archive Recording Descriptor Poller - Aeron
Archive Recording Signal - Struct containing the details of a recording signal.
- Aeron
Archive Recording Signal Consumer Func Logger - Aeron
Archive Recording Subscription Descriptor - Struct containing the details of a recording subscription
- Aeron
Archive Recording Subscription Descriptor Consumer Func Logger - Aeron
Archive Recording Subscription Descriptor Poller - Aeron
Archive Replay Merge - Aeron
Archive Replay Params - Struct containing the available replay parameters.
- Aeron
Archive Replay Params Builder - Fluent builder for
AeronArchiveReplayParams, starting from aeron’s defaults (every fieldAERON_NULL_VALUE: replay from the recording start to its end, with the context-default file IO length and no bounding counter). - Aeron
Archive Replication Params - Struct containing the available replication parameters.
- Aeron
Archive Replication Params Builder - Fluent builder for
AeronArchiveReplicationParams, starting from aeron’s defaults: replicate into a new recording at the destination, no live merge, the context’s default replication channel, and no credentials. - Aeron
Archive Replication Params Owned AeronArchiveReplicationParamsplus the string storage its C struct points into.- Aeron
Async AddCounter - Aeron
Async AddExclusive Publication - Aeron
Async AddPublication - Aeron
Async AddSubscription - Aeron
Async Destination - Aeron
Async Destination ById - Aeron
Async GetNext Available Session Id - Aeron
Available Counter Logger - Aeron
Available Counter Pair - Aeron
Available Image Logger - Aeron
Block Handler Logger - Aeron
Buffer Claim - Structure used to hold information for a try_claim function call.
- AeronC
Error - Aeron C API error: code + optional message.
- Aeron
Claim - Zero-copy claim on a publication’s term buffer with a RAII commit-or-abort lifecycle.
- Aeron
Client Registering Resource - Aeron
Close Client Logger - Aeron
Close Client Pair - Aeron
Cnc - Aeron
CncConstants - Aeron
CncMetadata - Aeron
Context - Aeron
Controlled Fragment Assembler - Aeron
Controlled Fragment Closure Assembler - Aeron
Controlled Fragment Handler Logger - Aeron
Counter - Aeron
Counter Constants - Configuration for a counter that does not change during its lifetime.
- Aeron
Counter Metadata Descriptor - Aeron
Counter Value Descriptor - Aeron
Counters Reader - Aeron
Counters Reader Buffers - Aeron
Counters Reader Foreach Counter Func Logger - Aeron
Data Header - Aeron
Data Header AsLongs - Aeron
Error - Aeron
Error Handler Logger - Aeron
Error LogReader Func Logger - Aeron
Error Logger - Production error handler that routes Aeron async errors through the Rust
logfacade at error level with a concise format — the recommended default forAeronContext::set_error_handler. - Aeron
Exclusive Publication - Aeron
Fprintf Handler Logger - Aeron
Fragment Assembler - Aeron
Fragment Closure Assembler - Aeron
Fragment Handler Logger - Aeron
Frame Header - Aeron
Header - Aeron
Header Values - Aeron
Header Values Frame - Aeron
Idle Strategy - Aeron
Idle Strategy Func Logger - Aeron
Image - Aeron
Image Constants - Configuration for an image that does not change during it’s lifetime.
- Aeron
Image Controlled Fragment Assembler - Aeron
Image Fragment Assembler - Aeron
Iovec - Aeron
IpcChannel Params - Aeron
LogBuffer - Aeron
Logbuffer Metadata - Aeron
Loss Reporter - Aeron
Loss Reporter Entry - Aeron
Loss Reporter Read Entry Func Logger - Aeron
Mapped Buffer - Aeron
Mapped File - Aeron
Mapped RawLog - Aeron
NakHeader - Aeron
NewPublication Logger - Aeron
NewSubscription Logger - Aeron
Notification Logger - Aeron
Option Header - Aeron
PerThread Error - Aeron
Publication - Aeron
Publication Constants - Configuration for a publication that does not change during it’s lifetime.
- Aeron
Publication Error Frame Handler Logger - Aeron
Publication Error Values - Aeron
Reserved Value Supplier Logger - Aeron
Resolution Header - Aeron
Resolution Header Ipv4 - Aeron
Resolution Header Ipv6 - Aeron
Response Setup Header - Aeron
Rttm Header - Aeron
Setup Header - Aeron
Status Message Header - Aeron
Status Message Optional Header - Aeron
Status Tracker - Status transition tracker that emits only when the observed
AeronStatusdiffers from the previously recorded state. - Aeron
StrTo PtrHash Map - Aeron
StrTo PtrHash MapFor Each Func Logger - Aeron
StrTo PtrHash MapKey - Aeron
Subscription - Aeron
Subscription Constants - Aeron
UdpChannel Params - Aeron
Unavailable Counter Logger - Aeron
Unavailable Counter Pair - Aeron
Unavailable Image Logger - Aeron
Uri - Aeron
UriParam - Aeron
UriParams - Aeron
UriParse Callback Logger - Aeron
UriString Builder - Channel
Uri - Represents the Aeron URI parser and handler.
- FnMut
Controlled Message Handler - FnMut
Message Handler - Handler
- Handler
- Handlers
- Utility method for setting empty handlers
- ManagedC
Resource - A custom struct for managing C resources with automatic cleanup.
- NoHandler
- Type-level “no callback” sentinel.
- Persistent
Subscription Builder - Builder for configuring and creating a persistent subscription. This provides a fluent interface for setting up a persistent subscription with proper CString handling.
- Recording
Descriptor - Recording descriptor for owned recording data
- Recording
Pos
Enums§
- Aeron
Archive Error Code - Archive control-response error codes (
io.aeron.archive.client.ArchiveException). - Aeron
Error Type - Aeron
Idle Strategy Kind - Aeron’s named idle strategies, as accepted by the context / media-driver
set_*_idle_strategyoptions (the Caeron_idle_strategy_loadsymbol table). - Aeron
Offer Error - Typed error for
offer/try_claimon a publication. - Aeron
Status - High-level connection state of a publication or subscription.
- Aeron
System Counter Type - CResource
- Control
Mode - Enum for control modes.
- Media
- Enum for media types.
Constants§
- AERON_
DIR_ PROP_ NAME - AERON_
IPC_ MEDIA - AERON_
UDP_ MEDIA - DRIVER_
TIMEOUT_ MS_ DEFAULT - MAX_
OFFER_ PARTS - Max buffer parts accepted by
AeronPublication::offer_parts/AeronExclusivePublication::offer_parts— theaeron_iovec_tarray is built on the stack, so it has a fixed capacity. Use the rawoffervwith your own iovec array for larger gathers. - PERSISTENT_
SUBSCRIPTION_ FROM_ LIVE - Sentinel for
PersistentSubscriptionBuilder::start_position: skip replay and join the live stream immediately. Maps to Aeron’sAERON_ARCHIVE_PERSISTENT_SUBSCRIPTION_FROM_LIVE. - PERSISTENT_
SUBSCRIPTION_ FROM_ START - Sentinel for
PersistentSubscriptionBuilder::start_position: replay from the beginning of the recording. Maps to Aeron’sAERON_ARCHIVE_PERSISTENT_SUBSCRIPTION_FROM_START. - PUBLICATION_
ADMIN_ ACTION - PUBLICATION_
BACK_ PRESSURED - PUBLICATION_
CLOSED - PUBLICATION_
ERROR - PUBLICATION_
MAX_ POSITION_ EXCEEDED - PUBLICATION_
NOT_ CONNECTED - Result codes returned by
AeronPublication::offer/try_claim(Aeronaeronc.h). A positive value is the resulting log position; the negatives classify the failure. - SOURCE_
LOCATION_ LOCAL - SOURCE_
LOCATION_ REMOTE - SPY_
PREFIX - TAG_
PREFIX
Statics§
Traits§
- Aeron
Agent Close Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Agent DoWork Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Agent Start Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Archive Credentials Challenge Supplier Func Callback - Callback to return encoded credentials given a specific encoded challenge.
- Aeron
Archive Credentials Encoded Credentials Supplier Func Callback - Callback to return encoded credentials.
- Aeron
Archive Credentials Free Func Callback - Callback to return encoded credentials so they may be reused or freed.
- Aeron
Archive Delegating Invoker Func Callback - Callback to allow execution of a delegating invoker to be run.
- Aeron
Archive Recording Descriptor Consumer Func Callback - Callback to return recording descriptors.
- Aeron
Archive Recording Signal Consumer Func Callback - Callback to return recording signals.
- Aeron
Archive Recording Subscription Descriptor Consumer Func Callback - Callback to return recording subscription descriptors.
- Aeron
Available Counter Callback - Function called by aeron_client_t to deliver notifications that a counter has been added to the driver.
- Aeron
Available Image Callback - Function called by aeron_client_t to deliver notifications that an aeron_image_t was added.
- Aeron
Block Handler Callback - Callback for handling a block of messages being read from a log.
- Aeron
Close Client Callback - Function called by aeron_client_t to deliver notifications that the client is closing.
- Aeron
Controlled Fragment Handler Callback - Callback for handling fragments of data being read from a log.
- Aeron
Counters Reader Foreach Counter Func Callback - Function called by aeron_counters_reader_foreach_counter for each counter in the aeron_counters_reader_t.
- Aeron
Error Handler Callback - The error handler to be called when an error occurs.
- Aeron
Error LogReader Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Fprintf Handler Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Fragment Handler Callback - Callback for handling fragments of data being read from a log.
- Aeron
Idle Strategy Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Loss Reporter Read Entry Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
NewPublication Callback - Function called by aeron_client_t to deliver notification that the media driver has added an aeron_publication_t or aeron_exclusive_publication_t successfully.
- Aeron
NewSubscription Callback - Function called by aeron_client_t to deliver notification that the media driver has added an aeron_subscription_t successfully.
- Aeron
Notification Callback - Generalised notification callback.
- Aeron
Publication Error Frame Handler Callback - The error frame handler to be called when the driver notifies the client about an error frame being received.
The data passed to this callback will only be valid for the lifetime of the callback. The user should use
aeron_publication_error_values_copyif they require the data to live longer than that. - Aeron
Reserved Value Supplier Callback - Function called when filling in the reserved value field of a message.
- Aeron
StrTo PtrHash MapFor Each Func Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Aeron
Unavailable Counter Callback - Function called by aeron_client_t to deliver notifications that a counter has been removed from the driver.
- Aeron
Unavailable Image Callback - Function called by aeron_client_t to deliver notifications that an aeron_image_t has been removed from use and should not be used any longer.
- Aeron
UriParse Callback Callback - (note you must copy any arguments that you use afterwards even those with static lifetimes)
- Controlled
Fragment Assemblable - A poll target whose raw fragments can be reassembled by
AeronControlledFragmentAssembler. - Fragment
Assemblable - A poll target whose raw fragments can be reassembled by
AeronFragmentAssembler. Implemented forAeronSubscriptionhere and for archive types in rusteron-archive. - IntoC
String - Persistent
Subscription Listener - Trait for persistent subscription event listeners. This provides a safe Rust alternative to using raw C function pointers.
Functions§
- find_
unused_ udp_ port - is_
udp_ port_ available - persistent_
subscription_ builder - Returns a builder for configuring a persistent subscription context
- validate_
endpoint_ for_ aeron_ udp - Validate a UDP channel URI endpoint (host:port) for use with Aeron.
Type Aliases§
- Cleanup
Box - RcOrArc
- Reference-counting smart pointer:
Rcby default,Arcunder themulti-threadedfeature. Swap is transparent —RcOrArc::new,.clone(),strong_countall work on both. - RefCell
OrMutex - Source
Location