listener-holder 0.1.1

A thread-safe single-listener holder with lock-free reads for Rust
Documentation
  • Coverage
  • 83.33%
    5 out of 6 items documented0 out of 5 items with examples
  • Size
  • Source code size: 26.27 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 1.47 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 15s Average build duration of successful builds.
  • all releases: 14s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • 0barman/listener-holder
    2 1 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • 0barman

listener-holder

A thread-safe, lock-free read single-listener holder for Rust.

Use it when you have one optional callback/listener that may be set or cleared at runtime, and you want to notify it from any thread without repeating RwLock<Option<...>> boilerplate.

Requirements

  • The listener type L must implement Send + Sync. The holder is then safe to share across threads (e.g. via Arc<ListenerHolder<L>>).

Features

  • Thread-safe: ListenerHolder<L> is Send + Sync when L: Send + Sync. Safe to share via Arc across threads.
  • Lock-free reads: Uses arc-swap internally; getting and notifying the listener do not take a lock. See docs/CONCURRENCY.md for comparison with RwLock<Option<Arc<L>>>.
  • Single listener: Holds at most one listener; setting a new one replaces the previous.
  • Simple API: set (pass None to clear), with_listener, get.

Usage

[dependencies]
listener-holder = "0.1.1"
use listener_holder::ListenerHolder;
use std::sync::Arc;

// Your listener type must be Send + Sync
struct MyListener;
impl MyListener {
    fn on_event(&self, msg: &str) {
        println!("event: {}", msg);
    }
}

let holder = ListenerHolder::new();

// Set listener
holder.set(Some(Arc::new(MyListener)));

// Notify (only if listener is set)
holder.with_listener(|l| l.on_event("hello"));

// Clear (pass None)
holder.set(None);
holder.with_listener(|l| l.on_event("ignored")); // no-op

// Get a clone of the current listener (e.g. to call from async code outside the lock)
if let Some(listener) = holder.get() {
    listener.on_event("from get()");
}

When to use

  • SDK or engine that exposes a single optional listener (e.g. connection listener, migration progress listener).
  • You were about to write RwLock<Option<Arc<dyn Listener>>> and want a ready-made type instead.

Panics

  • with_listener does not panic by itself. If the closure you pass panics, the holder is left unchanged and other threads can continue to use it.
  • No other method panics under normal use.

License

MIT OR Apache-2.0