Status
Active development. v0.4.0 ships the complete synchronous foundation:
SyncRegistry, priority ordering, panic isolation, and RAII guards. See
.dev/ROADMAP.md for the path to 1.0.
Public API is not yet frozen — minor releases may break it. Pin specific versions; expect changes pre-1.0.
Highlights
SyncRegistry<E>— generic over the event type. Handlers receive&E.- Lock-free reads via
ArcSwapsnapshots. Many threads cannotifyconcurrently with no coordination. - Zero allocation on the no-panic notify path.
- Panic isolation — a panicking handler does not stop siblings nor
propagate to the caller. Optional
on_paniccallback for observability. - Priority ordering —
register_with_priority(i32, ...). Higher fires first; ties broken in registration order. - RAII guards —
register_guardreturns aHandlerGuardthat unregisters on drop. Send + Sync— share registries freely across threads.- Cross-platform — Linux, macOS, Windows.
When to use it
Use registry-io when you have:
- Multiple components that need notification when something happens (config reload, 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
[]
= "0.4"
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
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/PERFORMANCE.md— cost model, benchmarks, and concurrency characteristics..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.
Copyright © 2026 James Gober. All rights reserved.