compact-waitgroup

A compact asynchronous WaitGroup synchronization primitive.
This crate is designed to be lightweight and executor-agnostic. It works with
any async runtime and supports no_std environments (requires alloc).
Usage
MonoWaitGroup
Using MonoWaitGroup for a single task:
use std::{thread, time::Duration};
use compact_waitgroup::MonoWaitGroup;
use futures_executor::block_on;
fn main() {
block_on(async {
let (wg, handle) = MonoWaitGroup::new();
thread::spawn(move || {
println!("Worker started");
thread::sleep(Duration::from_secs(1));
println!("Worker finished");
handle.done();
});
wg.await;
println!("All done!");
});
}
WaitGroup
Using WaitGroup for multiple tasks:
use std::{iter::repeat_n, thread, time::Duration};
use compact_waitgroup::WaitGroup;
use futures_executor::block_on;
fn main() {
block_on(async {
let (wg, base_handle) = WaitGroup::new();
for (i, handle) in repeat_n(base_handle, 8).enumerate() {
thread::spawn(move || {
println!("Task {i} started");
thread::sleep(Duration::from_secs(1));
println!("Task {i} finished");
handle.done();
});
}
wg.await;
println!("All done!");
});
}
Tokio Example
Works seamlessly with Tokio:
use std::{iter::repeat_n, time::Duration};
use compact_waitgroup::{WaitGroup, WithWorkerHandle};
use tokio::time::sleep;
#[tokio::main]
async fn main() {
let (wg, base_handle) = WaitGroup::new();
for (i, handle) in repeat_n(base_handle, 8).enumerate() {
let task = async move {
println!("Task {i} started");
sleep(Duration::from_secs(1)).await;
println!("Task {i} finished");
}
.with_worker_handle(handle);
tokio::spawn(task);
}
wg.await;
println!("All done!");
}
Memory Layout
This crate is optimized for size. By enabling the compact-mono feature,
MonoWaitGroup becomes even smaller by removing the unnecessary reference
counter.
| Component |
Default (64-bit) |
With compact-mono |
Saving |
WaitGroup |
32 bytes |
32 bytes |
0 bytes |
MonoWaitGroup |
32 bytes |
24 bytes |
8 bytes |
License
Licensed under either of
at your option.