14 releases
0.5.4 | Oct 7, 2024 |
---|---|
0.5.3 | Jul 9, 2023 |
0.5.2 | May 13, 2023 |
0.4.4 | Feb 22, 2023 |
0.3.0 | Aug 11, 2021 |
#102 in Rust patterns
84,212 downloads per month
Used in 109 crates
(33 directly)
59KB
807 lines
Overview
async_once_cell
is a version of once_cell
that adds support for async initialization of cells. The short version of the
API is:
impl OnceCell<T> {
fn new() -> OnceCell<T>;
fn get(&self) -> Option<&T>;
async fn get_or_init(&self, init: impl Future<Output=T>) -> &T;
}
More patterns and use-cases are in the docs!
lib.rs
:
A collection of lazy initialized values that are created by Future
s.
[OnceCell]'s API is similar to the once_cell
crate,
std::cell::OnceCell
, or std::sync::OnceLock
. It provides an async version of a cell
that can only be initialized once, permitting tasks to wait on the initialization if it is
already running instead of racing multiple initialization tasks.
Unlike threads, tasks can be cancelled at any point where they block. [OnceCell] deals with
this by allowing another initializer to run if the task currently initializing the cell is
dropped. This also allows for fallible initialization using OnceCell::get_or_try_init and
for the initializing Future
to contain borrows or use references to thread-local data.
[Lazy] takes the opposite approach: it wraps a single Future
which is cooperatively run to
completion by any polling task. This requires that the initialization function be independent
of the calling context, but will never restart an initializing function just because the
surrounding task was cancelled. Using a trait object (Pin<Box<dyn Future>>
) for the future
may simplify using this type in data structures.
Overhead
Both cells use two usize
s to store state and do not retain any allocations after
initialization is complete. Allocations are only required if there is contention.
Accessing an already-initialized cell is as cheap as possible: only one atomic load with Acquire ordering.
Features
The critical-section
feature
If this feature is enabled, the critical-section
crate is used instead of an std
mutex. You must depend on that crate and select a locking
implementation; see its documentation for details.
The std
feature
This is currently a no-op, but might in the future be used to expose APIs that depends on
types only in std
. It does not control the locking implementation.