asyncband/lib.rs
1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#![cfg_attr(docsrs, feature(doc_cfg))]
19#![deny(missing_docs)]
20
21//! Composable, runtime-agnostic concurrency building blocks for async Rust.
22//!
23//! `asyncband` provides synchronization, initialization, task coordination, channels, resource
24//! reuse, and workload control without choosing an executor for the application. Its async APIs use
25//! standard futures and wakers, so they can run on Tokio, async-std, smol, or a custom executor.
26//!
27//! # Getting started
28//!
29//! Public APIs are enabled through opt-in Cargo features, and no features are enabled by default.
30//! Enable the APIs your application needs:
31//!
32//! ```toml
33//! asyncband = { version = "0.7", features = ["mutex", "oneshot"] }
34//! ```
35//!
36//! Then use the selected APIs directly:
37//!
38//! ```
39//! # #[cfg(feature = "mutex")]
40//! # #[tokio::main]
41//! # async fn main() {
42//! use asyncband::mutex::Mutex;
43//!
44//! let counter = Mutex::new(0);
45//! {
46//! let mut value = counter.lock().await;
47//! *value += 1;
48//! }
49//! assert_eq!(*counter.lock().await, 1);
50//! # }
51//! # #[cfg(not(feature = "mutex"))]
52//! # fn main() {}
53//! ```
54//!
55//! # API map
56//!
57//! | Area | API | Feature | Use |
58//! |----------------------------|-----------------------------------------------|----------------|---------------------------------------------------------------------------------------------------------------|
59//! | Locks and conditions | [`Mutex`](mutex::Mutex) | `mutex` | Protect shared data with asynchronous mutual exclusion. |
60//! | | [`RwLock`](rwlock::RwLock) | `rwlock` | Allow multiple readers or one writer. |
61//! | | [`Condvar`](condvar::Condvar) | `condvar` | Wait for notifications while releasing a mutex. |
62//! | Coordination | [`Semaphore`](semaphore::Semaphore) | `semaphore` | Limit concurrent work by acquiring permits. |
63//! | | [`Barrier`](barrier::Barrier) | `barrier` | Synchronize a fixed number of participants at a reusable rendezvous. |
64//! | | [`ManualResetEvent`](event::ManualResetEvent) | `event` | Signal current and future waits until explicitly reset. |
65//! | | [`Latch`](latch::Latch) | `latch` | Wait until a fixed one-way countdown reaches zero. |
66//! | | [`WaitGroup`](waitgroup::WaitGroup) | `waitgroup` | Dynamically register participants and wait until all have completed. |
67//! | | [`Shutdown`](shutdown::Shutdown) | `shutdown` | Request shutdown and wait until all completion guards are dropped. |
68//! | Work coalescing | [`Once`](once::Once) | `once` | Complete one asynchronous initialization; cancelled or panicked attempts may be retried. |
69//! | | [`OnceCell`](once::OnceCell) | `once-cell` | Store one value from an access-time initializer; failed, cancelled, or panicked attempts may be retried. |
70//! | | [`LazyCell`](once::LazyCell) | `lazy-cell` | Initialize one value with a stored function and resume the same in-flight future after caller cancellation. |
71//! | | [`OnceMap`](once::OnceMap) | `once-map` | Coalesce work per key and retain each successful value until explicitly removed. |
72//! | | [`Group`](singleflight::Group) | `singleflight` | Coalesce overlapping work per key without retaining completed values. |
73//! | Communication | [`Completion`](completion::Completion) | `completion` | Publish one shared result to any number of current and future observers. |
74//! | | [`oneshot`] | `oneshot` | Send one value from one sender to one receiver. |
75//! | | [`mpsc`] | `mpsc` | Send each value from multiple producers to one receiver with bounded backpressure or an unbounded queue. |
76//! | | [`broadcast`] | `broadcast` | Deliver every value to receivers active at send time; retain an unbounded backlog until each consumes or drops. |
77//! | | [`watch`] | `watch` | Publish cloneable latest state from one or more senders; receivers independently coalesce intermediate updates. |
78//! | Object reuse | [`pool`] | `pool` | Reuse objects through bounded or unbounded pool variants. |
79//! | Sync interop | [`FutureExt`](blocking::FutureExt) | `blocking` | Drive one runtime-agnostic future from a blocking thread. |
80//!
81//! # Scope and runtime model
82//!
83//! The project is not limited to small or stateless primitives. Stateful tools such as
84//! [`singleflight::Group`] and the [`pool`] module fit when they provide reusable coordination and
85//! remain independent of executor policy.
86//!
87//! The async APIs do not start threads, spawn tasks, install timers, or require a runtime-specific
88//! reactor. Task placement, deadlines, retries, periodic maintenance, and lifecycle orchestration
89//! remain with the caller. Await Asyncband futures inside any executor that polls standard Rust
90//! futures, and compose those runtime services around them.
91//!
92//! # Async first, blocking by adaptation
93//!
94//! Async and synchronous primitives have different optimization constraints. Asyncband designs its
95//! primitives for async use and provides the optional [`blocking`] module as a boundary adapter
96//! instead of duplicating synchronous methods across every type. Sync-first implementations can
97//! exploit OS- or platform-specific facilities and remain the domain of dedicated libraries.
98//!
99//! The adapter polls one future on the calling thread. It is not a general-purpose async runtime,
100//! and futures that depend on a runtime-specific timer or I/O driver may not make progress. See the
101//! module documentation for the full execution constraints.
102//!
103//! # Thread safety
104//!
105//! Asyncband types implement `Send` and `Sync` only when their protected, transferred, or managed
106//! values satisfy the required bounds. Consult each API's documentation for its exact contract.
107//!
108//! # Disclaimer
109//!
110//! Apache Asyncband (Incubating) is an effort undergoing incubation at the Apache Software
111//! Foundation (ASF), sponsored by the Apache Incubator PMC.
112//!
113//! Incubation is required of all newly accepted projects until a further review indicates that the
114//! infrastructure, communications, and decision-making process have stabilized in a manner
115//! consistent with other successful ASF projects.
116//!
117//! While incubation status is not necessarily a reflection of the completeness or stability of the
118//! code, it does indicate that the project has yet to be fully endorsed by the ASF.
119mod internal;
120
121#[cfg(feature = "barrier")]
122pub mod barrier;
123#[cfg(feature = "blocking")]
124pub mod blocking;
125#[cfg(feature = "broadcast")]
126pub mod broadcast;
127#[cfg(feature = "completion")]
128pub mod completion;
129#[cfg(feature = "condvar")]
130pub mod condvar;
131#[cfg(feature = "event")]
132pub mod event;
133#[cfg(feature = "latch")]
134pub mod latch;
135#[cfg(feature = "mpsc")]
136pub mod mpsc;
137#[cfg(feature = "mutex")]
138pub mod mutex;
139#[cfg(any(
140 feature = "lazy-cell",
141 feature = "once",
142 feature = "once-cell",
143 feature = "once-map"
144))]
145pub mod once;
146#[cfg(feature = "oneshot")]
147pub mod oneshot;
148#[cfg(feature = "pool")]
149pub mod pool;
150#[cfg(feature = "rwlock")]
151pub mod rwlock;
152#[cfg(feature = "semaphore")]
153pub mod semaphore;
154#[cfg(feature = "shutdown")]
155pub mod shutdown;
156#[cfg(feature = "singleflight")]
157pub mod singleflight;
158#[cfg(feature = "waitgroup")]
159pub mod waitgroup;
160#[cfg(feature = "watch")]
161pub mod watch;
162
163#[cfg(all(test, any(feature = "once-map", feature = "singleflight")))]
164mod test_support;