Skip to main content

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;