Expand description
Executor-agnostic bounded async streams for FFI callbacks.
BoundedAsyncStream<T> is a generic, runtime-agnostic stream primitive
designed for wrapping Apple SDK callback / delegate / KVO patterns:
- Bounded — backed by a fixed-capacity
VecDeque. When the buffer is full and a new item arrives from the producer, the oldest queued item is dropped to make room (lossy by design). - Waker-driven — implements
std::future::Futurevia a storedWaker; works with any executor (tokio, async-std, smol, futures, etc.) without requiring a runtime feature. Send + Sync— produces and consumes can live on different threads, locked by a singleMutex.
The lossy-oldest-drop policy is the right default for real-time event
streams (UI input, frame capture, BLE notifications, location updates):
a slow consumer should always see the latest event, not a stale queue.
When you instead need back-pressure (every event must be delivered),
use AsyncStreamSender::push_or_block which blocks the producer
until the consumer drains capacity.
§Example
use doom_fish_utils::stream::BoundedAsyncStream;
use std::sync::Arc;
// 8-element ring buffer of `String` events.
let (stream, sender) = BoundedAsyncStream::<String>::new(8);
// Producer side: typically a Swift delegate / extern "C" callback
// running on a background queue.
std::thread::spawn(move || {
for i in 0..100 {
sender.push(format!("event #{i}"));
}
drop(sender); // closes the stream
});
// Consumer side: any async runtime.
while let Some(event) = stream.next().await {
println!("got {event}");
}Structs§
- Async
Stream Sender - Producer handle for a
BoundedAsyncStream. - Bounded
Async Stream - A bounded, lossy-by-default, executor-agnostic async stream.
- Next
Item - Future returned by
BoundedAsyncStream::next.