Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,17 @@ All notable changes to this project will be documented in this file.

* Add an opt-in `asyncband::blocking::FutureExt` bridge with `block_on` and `wait_timeout` methods for waiting on runtime-agnostic futures from synchronous code.
* Add opt-in bounded and unbounded runtime-agnostic object pools under `asyncband::pool`.
* Add opt-in SPSC, SPMC, and MPMC competing queues with topology-specific endpoint capabilities.
* Add opt-in lossless bounded and unbounded SPMC and MPMC broadcast channels.
* Add an opt-in latest-state watch channel.
* Add a `channel` umbrella feature that enables every channel API while keeping their public paths at the crate root.

### Breaking changes

* Gate all exported primitives behind opt-in Cargo features and enable no features by default; downstream dependencies must explicitly enable the APIs they use.
* Remove `admission::FairShare` and its `admission` Cargo feature from the feature set.
* Remove the `asyncband::atomicbox` module and its `AtomicBox` and `AtomicOptionBox` types from the public API.
* Remove the lossy `broadcast::overflow` channel and its `broadcast` Cargo feature; future broadcast APIs will use explicit bounded and unbounded lossless semantics.
* Remove the lossy `broadcast::overflow` API; the `broadcast` Cargo feature now selects explicit bounded and unbounded lossless channels.
* Remove `Semaphore::try_acquire_and_forget`, `Semaphore::acquire_and_forget`, `Semaphore::try_acquire_owned_and_forget`, and `Semaphore::acquire_owned_and_forget`; acquire a permit and call its `forget` method instead.
* Rename `oneshot::Sender::is_closed` and `oneshot::Receiver::is_closed` to `is_disconnected`.
* Replace `Semaphore::forget` with `Semaphore::drain_permits` and `Semaphore::forget_exact` with `Semaphore::reduce_permits`; permit-level `forget` methods are unchanged.
Expand Down
2 changes: 2 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ Asyncband collects composable, runtime-agnostic concurrency building blocks info
- `condvar::Condvar` is inspired by [`std::sync::Condvar`](https://doc.rust-lang.org/std/sync/struct.Condvar.html) and [`async_std::sync::Condvar`](https://docs.rs/async-std/latest/async_std/sync/struct.Condvar.html), with a fair FIFO waiter queue and standard non-buffered notification semantics.
- `latch::Latch` is inspired by [`latches`](https://github.com/mirromutth/latches), with a different implementation based on the internal `CountdownState` primitive.
- `mutex::Mutex` is derived from [`tokio::sync::Mutex`](https://docs.rs/tokio/latest/tokio/sync/struct.Mutex.html).
- The cloneable competing-receiver topology of `spmc` and `mpmc` is informed by [`flume`](https://github.com/zesterer/flume), with an independent runtime-agnostic implementation built on Asyncband's waiter arena.
- `once::OnceCell` is derived from [`tokio::sync::OnceCell`](https://docs.rs/tokio/latest/tokio/sync/struct.OnceCell.html), but uses Asyncband's semaphore implementation.
- `once::OnceMap` is inspired by [`uv-once-map`](https://github.com/astral-sh/uv/tree/main/crates/uv-once-map), with a redesigned interface and implementation.
- `oneshot::channel` is derived from the [`oneshot`](https://github.com/faern/oneshot) crate, with significant simplifications because Asyncband does not provide synchronized receive operations.
- `pool` is ported from [`fastpool`](https://github.com/fast/fastpool), which is derived from [`deadpool`](https://github.com/bikeshedder/deadpool), while keeping Fastpool's runtime-agnostic design and caller-side timeout composition.
- `rwlock::RwLock` is derived from [`tokio::sync::RwLock`](https://docs.rs/tokio/latest/tokio/sync/struct.RwLock.html), but accepts any `NonZeroUsize` as `max_readers` instead of Tokio's restricted range.
- `semaphore::Semaphore` is derived from [`tokio::sync::Semaphore`](https://docs.rs/tokio/latest/tokio/sync/struct.Semaphore.html), but omits `close`, avoids Tokio's fixed maximum-permit constant, and adds operations such as `reduce_permits` for Asyncband's use cases.
- `waitgroup::WaitGroup` is inspired by [`waitgroup-rs`](https://github.com/laizy/waitgroup-rs), with a different API and an implementation based on the internal `CountdownState` primitive.
- `watch` is inspired by [`tokio::sync::watch`](https://docs.rs/tokio/latest/tokio/sync/watch/), but returns owned `Arc` snapshots instead of runtime-specific borrow guards.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ async fn increment() {
}
```

Public paths stay direct—such as `asyncband::mutex`, `asyncband::pool`, and `asyncband::once::OnceCell`—while Cargo features keep unused implementations out of the build.
Public paths stay direct—such as `asyncband::mutex`, `asyncband::mpsc`, and `asyncband::once::OnceCell`—while Cargo features keep unused implementations out of the build. The `channel` feature enables every channel API without adding an `asyncband::channel` namespace.

## API map

Expand All @@ -71,8 +71,14 @@ Public paths stay direct—such as `asyncband::mutex`, `asyncband::pool`, and `a
| | [`WaitGroup`](https://docs.rs/asyncband/*/asyncband/waitgroup/struct.WaitGroup.html) | `waitgroup` | Wait for a dynamic group of tasks to finish. |
| | [`shutdown`](https://docs.rs/asyncband/*/asyncband/shutdown/) | `shutdown` | Coordinate shutdown signals and completion. |
| Channels | [`oneshot::channel`](https://docs.rs/asyncband/*/asyncband/oneshot/fn.channel.html) | `oneshot` | Send one value between two tasks. |
| | [`spsc`](https://docs.rs/asyncband/*/asyncband/spsc/) | `spsc` | Queue each value for one producer and one receiver. |
| | [`mpsc::bounded`](https://docs.rs/asyncband/*/asyncband/mpsc/fn.bounded.html) | `mpsc` | Send values from multiple producers through a bounded channel. |
| | [`mpsc::unbounded`](https://docs.rs/asyncband/*/asyncband/mpsc/fn.unbounded.html) | `mpsc` | Send values from multiple producers through an unbounded channel. |
| | [`spmc`](https://docs.rs/asyncband/*/asyncband/spmc/) | `spmc` | Let multiple receivers compete for values from one producer. |
| | [`mpmc`](https://docs.rs/asyncband/*/asyncband/mpmc/) | `mpmc` | Let multiple producers and receivers share a competing queue. |
| | [`broadcast::spmc`](https://docs.rs/asyncband/*/asyncband/broadcast/spmc/) | `broadcast` | Broadcast every value from one producer to every subscription. |
| | [`broadcast::mpmc`](https://docs.rs/asyncband/*/asyncband/broadcast/mpmc/) | `broadcast` | Broadcast one committed order from concurrent producers. |
| | [`watch`](https://docs.rs/asyncband/*/asyncband/watch/) | `watch` | Retain the latest state and coalesce intermediate updates. |
| Resource reuse | [`pool::bounded`](https://docs.rs/asyncband/*/asyncband/pool/bounded/) | `pool` | Reuse managed objects up to a configured capacity. |
| | [`pool::unbounded`](https://docs.rs/asyncband/*/asyncband/pool/unbounded/) | `pool` | Reuse manually supplied or manager-created objects. |
| Workload coordination | [`Semaphore`](https://docs.rs/asyncband/*/asyncband/semaphore/struct.Semaphore.html) | `semaphore` | Control concurrent access with permits. |
Expand Down
6 changes: 6 additions & 0 deletions asyncband/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ default = []

barrier = []
blocking = []
broadcast = []
channel = ["broadcast", "mpmc", "mpsc", "oneshot", "spmc", "spsc", "watch"]
condvar = ["mutex"]
latch = []
mpmc = []
mpsc = []
mutex = []
once = ["semaphore"]
Expand All @@ -59,7 +62,10 @@ rwlock = []
semaphore = []
shutdown = ["latch", "waitgroup"]
singleflight = ["dep:hashbrown", "once-cell"]
spmc = []
spsc = []
waitgroup = []
watch = []

[dependencies]
hashbrown = { workspace = true, default-features = false, features = [
Expand Down
Loading