pub struct Listener<T> { /* private fields */ }Expand description
A listener that waits for an announced value.
This type is Clone and can be shared across multiple tasks or threads.
All clones will receive the same value when it’s announced.
§Examples
use announcement::Announcement;
let (announcer, announcement) = Announcement::new();
let listener = announcement.listener();
announcer.announce(42).unwrap();
assert_eq!(listener.try_listen(), Some(42));Implementations§
Source§impl<T: Clone> Listener<T>
impl<T: Clone> Listener<T>
Sourcepub fn try_listen(&self) -> Option<T>
pub fn try_listen(&self) -> Option<T>
Try to receive without waiting.
Returns Some(value) if a value has been announced, or None if not yet announced.
§Performance
O(1), ~5-10ns, non-blocking
§Examples
use announcement::Announcement;
let (announcer, announcement) = Announcement::new();
let listener = announcement.listener();
assert_eq!(listener.try_listen(), None);
announcer.announce(42).unwrap();
assert_eq!(listener.try_listen(), Some(42));Sourcepub fn is_closed(&self) -> bool
pub fn is_closed(&self) -> bool
Check if the announcer was closed without announcing.
Returns true if the announcer was explicitly closed or dropped without announcing.
This is a non-blocking, lock-free operation.
§Performance
O(1), ~5-10ns
§Examples
use announcement::Announcement;
let (announcer, announcement) = Announcement::<i32>::new();
let listener = announcement.listener();
assert!(!listener.is_closed());
drop(announcer);
assert!(listener.is_closed());Source§impl<T: Clone> Listener<T>
impl<T: Clone> Listener<T>
Sourcepub async fn listen(&self) -> Result<T, ListenError>
pub async fn listen(&self) -> Result<T, ListenError>
Wait for and receive the announced value (async).
Waits until a value is announced or the announcer is closed. Multiple calls return the same result.
§Returns
Ok(value)- A value was announcedErr(ListenError::Closed)- The announcer was dropped or closed without announcing
§Cancel Safety
This method is cancel-safe. Dropping the future (e.g., via select! or timeout)
will not lose the announced value. The value remains available for subsequent calls
to listen() or try_listen().
You can safely use this method with:
tokio::select!- Choose between multiple futurestokio::time::timeout- Add a timeout- Any other cancellation mechanism
§Multiple Calls
Calling listen() multiple times (even after it returns) will always return the
same value. The value is stored in an Arc<OnceLock> and cloned for each listener.
§Performance
- Fast path (already announced): ~5-10ns
- Slow path (waiting): ~100ns + wait time
§Examples
use announcement::Announcement;
let (announcer, announcement) = Announcement::new();
let listener = announcement.listener();
tokio::spawn(async move {
announcer.announce(42).unwrap();
});
let value = listener.listen().await.unwrap();
assert_eq!(value, 42);Source§impl<T: Clone> Listener<T>
impl<T: Clone> Listener<T>
Sourcepub fn listen_blocking(&self) -> Result<T, ListenError>
pub fn listen_blocking(&self) -> Result<T, ListenError>
Blocking wait for the announced value.
This method blocks the current thread until a value is announced or the announcer is closed. FOR NON-ASYNC CONTEXTS ONLY.
Requires: std feature (enabled by default)
§Returns
Ok(value)- A value was announcedErr(ListenError::Closed)- The announcer was dropped or closed without announcing
§⚠️ Warning: Async Context
DO NOT use this method in async functions or tasks. It will block the executor thread, preventing other tasks from running. This can cause:
- Deadlocks in async runtimes
- Poor performance degradation
- Runtime warnings or panics
In async contexts, use listen() instead.
§When to Use
Use this method when:
- You’re in a non-async context (regular threads, main function)
- You want to synchronize between threads using standard library threads
- You’re interfacing with blocking APIs
§Thread Safety
This method is thread-safe and can be called from any thread. Multiple threads can block on different listeners simultaneously.
§Examples
use announcement::Announcement;
use std::thread;
use std::time::Duration;
let (announcer, announcement) = Announcement::new();
let listener = announcement.listener();
thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
announcer.announce(42).unwrap();
});
let value = listener.listen_blocking().unwrap();
assert_eq!(value, 42);Sourcepub fn listen_timeout_blocking(
&self,
duration: Duration,
) -> Result<T, ListenError>
pub fn listen_timeout_blocking( &self, duration: Duration, ) -> Result<T, ListenError>
Blocking wait with timeout.
Returns the value if it’s announced within the timeout period.
Requires: std feature (enabled by default)
§Returns
Ok(val)- Value received within timeoutErr(ListenError::Timeout)- Timeout elapsed without receiving a valueErr(ListenError::Closed)- The announcer was dropped or closed without announcing
§⚠️ Warning: Async Context
DO NOT use this method in async functions or tasks. It will block the executor
thread. In async contexts, use listen() with tokio::time::timeout
or similar timeout mechanisms instead.
§Examples
use announcement::Announcement;
use std::time::Duration;
let (announcer, announcement) = Announcement::new();
let listener = announcement.listener();
announcer.announce(42).unwrap();
let result = listener.listen_timeout_blocking(Duration::from_secs(1));
assert_eq!(result, Ok(42));