Highlights
- Cross-platform — Linux, macOS, Windows.
- Lock-free reads via
ArcSwapsnapshots. Many threads cannotifyconcurrently with no coordination. - Zero allocation on the no-panic sync notify path.
- Panic isolation — a panicking handler does not stop siblings nor
propagate to the caller. Optional
on_paniccallback for observability. Works for both sync handlers and async futures. - Priority ordering —
register_with_priority(i32, ...). Higher fires first; ties broken in registration order. SyncRegistry<E>— generic over the event type. Handlers receive&E.AsyncRegistry<E>(feature:async) — same lock-free storage, futures-returning handlers, concurrent or sequential dispatch.- RAII guards —
register_guardreturns aHandlerGuard/AsyncHandlerGuardthat unregisters on drop. Send + Sync— share registries freely across threads.
Status
Stable. Production-ready. registry-io 1.0.0 is the first
stable release. The public API is frozen per the contract in
docs/STABILITY-1.0.md; breaking changes
require a major-version bump. Performance, panic-isolation, and
zero-allocation guarantees are measured and locked in.
Headline numbers (full table in
docs/PERFORMANCE.md):
- Sync
notify, 1 handler, 1 thread — 10.1 ns - Sync
notify, 4 handlers, 16 threads contended — 24.7 ns - Async
notifyconcurrent, 1 handler — 177 ns - Async
notify_sequential, 1 handler — 53 ns - Sync
notifyhot path heap allocations — 0 (verified bydhat)
Guarantees:
- Zero
unsafein the public API. - Lock-free reads via
ArcSwapsnapshots. - Zero allocation on the sync notify no-panic path.
- Panic isolation — one panicking handler does not stop siblings or propagate to the caller.
- Priority-ordered dispatch with stable ties.
- RAII unregistration via
HandlerGuard/AsyncHandlerGuard. Send + Syncon every public type.- Cross-platform — Linux, macOS, Windows on stable + MSRV 1.85.0.
When to use it
Use registry-io when you have:
- Multiple components that need notification when something happens (
configreload,file change,transaction commit,metric event, etc.). - Fast, in-process handlers measured in microseconds or less.
- A need to register and unregister handlers dynamically.
- Performance-critical paths where channel allocation would dominate.
Do not use registry-io when you have:
- Cross-process or cross-network delivery needs — use NATS, Redis pub/sub, or similar message brokers.
- Heavy handler workloads requiring backpressure — use
tokio::sync::broadcastor channels. - Event sourcing or durability requirements — use a real event log.
Quick start
[]
= "1.0"
use Arc;
use ;
use SyncRegistry;
let registry: = new;
let total = new;
let sink = clone;
let id = registry.register;
registry.notify;
registry.notify;
assert_eq!;
assert!;
Priority ordering
use ;
use SyncRegistry;
let registry: = new;
let order = new;
let o = clone;
let _ = registry.register_with_priority;
let o = clone;
let _ = registry.register;
let o = clone;
let _ = registry.register_with_priority;
registry.notify;
assert_eq!;
RAII guards
use Arc;
use SyncRegistry;
let registry = new;
// guard drops here -> handler is unregistered
assert!;
Panic isolation
use SyncRegistry;
let registry: = new;
registry.on_panic;
let _ = registry.register;
let _ = registry.register;
registry.notify; // returns cleanly; both effects observed
Async handlers (feature: async)
[]
= { = "1.0", = ["async"] }
= { = "1", = ["rt-multi-thread", "macros"] }
use Arc;
use ;
use r#AsyncRegistry;
async
Same lock-free read path as SyncRegistry. Panics in handler futures are
caught via an internal CatchUnwind adapter and surfaced through
on_panic, just like sync handlers.
See examples/ for runnable programs and docs/API.md
for the full reference.
Design philosophy
- Sync-first. The fast path is synchronous, runs on the calling thread, allocates nothing, and dispatches in nanoseconds.
- Lock-free reads. Multiple threads can call
notify()concurrently without contention. - Zero allocation on the hot path. Notify walks the handler list and dispatches without any heap allocation in the no-panic case.
- Focused scope. This is a local, in-process notification primitive. Not a message bus, not a distributed event system, not a pub/sub broker.
Documentation
docs/API.md— full API reference with examples per item.docs/PATTERNS.md— four canonical integration patterns (hot reload, audit fan-out, metric events, transaction hooks), each with a runnable example.docs/ARCHITECTURE.md— internal structure walk-through, hot/slow path code excerpts, design decisions.docs/PERFORMANCE.md— cost model, benchmarks, and concurrency characteristics.docs/SECURITY.md— threat model, panic isolation detail, fuzz methodology.docs/STABILITY-1.0.md— the v1.0 stability contract (what's frozen, what can change).docs/PLATFORM-NOTES.md— per-platform behavior nuances (Linux/macOS/Windows)..dev/ROADMAP.md— milestone plan to 1.0.CHANGELOG.md— release history.
Standards
- REPS (Rust Efficiency & Performance Standards) governs every decision.
See
REPS.md. - MSRV: Rust 1.85.
- Edition: 2024.
- Cross-platform: Linux, macOS, Windows.
License
Dual-licensed under either of:
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT License (LICENSE-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.