pub struct AsyncCell<T = ()> { /* private fields */ }Expand description
An async primitive. Similar to a Cell<Option<T>> but awaitable.
This type should generally have much lower overhead vs an equivalent
channel although it may not handle heavy contention as well. In fact,
it may only be a few bytes larger than T itself.
Implementations§
Source§impl<T> AsyncCell<T>
impl<T> AsyncCell<T>
Sourcepub fn set(&self, value: T)
pub fn set(&self, value: T)
Set the value of the cell. If it was previously empty, wake up a
single arbitrary call take and/or all calls
to get.
This is probably the most important function in the whole crate since it can be used to resolve some future X with some value Y at a distance.
use async_cell::sync::AsyncCell;
let cell = AsyncCell::shared();
let message = cell.take_shared();
spawn(async move {
println!("{}", message.await)
});
cell.set("Hello, World!");Sourcepub fn take(&self) -> Take<&Self> ⓘ
pub fn take(&self) -> Take<&Self> ⓘ
Once woken up with a value, remove it and resolve.
use async_cell::sync::AsyncCell;
let cell1 = AsyncCell::shared();
let cell2 = cell1.clone();
spawn(async move {
cell1.set(vec![1i32, 2, 3]);
});
assert_eq!(&cell2.take().await, &[1, 2, 3]);
// Awaiting again on the cell would block forever!
// The value is now None.
assert_eq!(cell2.try_take(), None);Technically, the returned type is just a reference to this cell.
It must be driven by await to actually move the internal data.
If borrowing this cell is unacceptable, consider directly
constructing the Take wrapper around a smart-pointer of your
own choosing.
Sourcepub fn get(&self) -> Get<&Self> ⓘwhere
T: Clone,
pub fn get(&self) -> Get<&Self> ⓘwhere
T: Clone,
Once woken up with a value, clone it and resolve.
use async_cell::sync::AsyncCell;
let cell1 = AsyncCell::shared();
let cell2 = cell1.clone();
spawn(async move {
cell1.set(vec![1i32, 2, 3]);
});
assert_eq!(&cell2.get().await, &[1, 2, 3]);
assert_eq!(&cell2.get().await, &[1, 2, 3]);Technically, the returned type is just a reference to this cell.
It must be driven by await to actually move the internal data.
If borrowing this cell is unacceptable, consider directly
constructing the Get wrapper around a smart-pointer of your
own choosing.
Sourcepub fn try_take(&self) -> Option<T>
pub fn try_take(&self) -> Option<T>
If the cell currently has a value, remove it.
use async_cell::sync::AsyncCell;
let cell = AsyncCell::new();
cell.set(420);
assert_eq!(cell.try_take(), Some(420));
assert_eq!(cell.try_take(), None);Sourcepub fn try_get(&self) -> Option<T>where
T: Clone,
pub fn try_get(&self) -> Option<T>where
T: Clone,
Clones the current value of the cell.
use async_cell::sync::AsyncCell;
let cell = AsyncCell::new();
// Value starts out empty.
assert_eq!(cell.try_get(), None);
cell.set(420);
// Value is now set.
assert_eq!(cell.try_get(), Some(420));Sourcepub fn or_set(&self, value: T)
pub fn or_set(&self, value: T)
Set the value of the cell if it is empty, waking up any attached futures.
Sourcepub fn replace(&self, value: T) -> Option<T>
pub fn replace(&self, value: T) -> Option<T>
Replace the value of the cell, returning the previous value. If the previous value is empty, wake up any attached futures.
Sourcepub fn update(&self, with: impl FnOnce(Option<T>) -> Option<T>)
pub fn update(&self, with: impl FnOnce(Option<T>) -> Option<T>)
Atomically update the value of this cell using the given function.
If the value transitions from None to Some, it acts like a call
to set. Otherwise it only effects the internals of the cell.
Note: avoid doing anything time consuming in the passed
function, since it will block any async runtime thread in the
process of poll-ing a Get or Take future.
Sourcepub fn update_some(&self, with: impl FnOnce(T) -> T)
pub fn update_some(&self, with: impl FnOnce(T) -> T)
Atomically update the value of this cell if it is set, using the given function.
Note: avoid doing anything time consuming in the passed
function, since it will block any async runtime thread in the
process of poll-ing a Get or Take future.
Sourcepub fn into_inner(self) -> Option<T>
pub fn into_inner(self) -> Option<T>
Destroys this cell, returning the value inside.
Sourcepub fn guard(&self, cancel: T) -> GuardedCell<T, &Self>
pub fn guard(&self, cancel: T) -> GuardedCell<T, &Self>
Used to ensure this cell is set to some value even when panicking or returning errors. This is useful in preventing deadlocks, signaling shutdown, etc.
use async_cell::sync::AsyncCell;
let latest_val = AsyncCell::shared();
let latest_val_ref = latest_val.clone();
let read_content = move |path: &str| -> Option<u32> {
let latest_val = latest_val_ref.guard(Err(format!("{:?} is not an int", path)));
let text = std::fs::read_to_string(path).ok()?;
let val = text.parse().ok()?;
latest_val.set(Ok(val));
Some(val)
};
spawn(async move {
if let Some(val) = read_content("test/hello.txt") {
send(val);
}
});
match latest_val.get().await {
Ok(text) => println!("{}", text),
Err(text) => eprintln!("Error: {}", text),
}Source§impl AsyncCell<()>
These are trivial wrappers around AsyncCell::set and
AsyncCell::take which are useful in the case where you want
“waking up” functionality, without any actual data being sent.
impl AsyncCell<()>
These are trivial wrappers around AsyncCell::set and AsyncCell::take which are useful in the case where you want “waking up” functionality, without any actual data being sent.
Source§impl<T> AsyncCell<T>
impl<T> AsyncCell<T>
Create an empty AsyncCell which can be shared between locations with
.clone().
Wraps an existing cell in a reference-counted pointer, so it can
be shared between locations with .clone().
Like take but doesn’t borrow self.
Like get but doesn’t borrow self.
Like guard but doesn’t borrow self.
Sourcepub fn take_weak(self: &Arc<Self>) -> TakeWeak<T> ⓘ
pub fn take_weak(self: &Arc<Self>) -> TakeWeak<T> ⓘ
Like take but creates a weak reference to self.
If all strong references to self are dropped, the returned future
will resolve to None even if the cell was full at the time.
use async_cell::sync::AsyncCell;
let cell = AsyncCell::shared();
let taker = cell.take_weak();
// The cell can be used normally
cell.set(42);
assert_eq!((&taker).await, Some(42));
// Will resolve after being dropped
spawn(async move {
cell.set(43); // any current value will be dropped
drop(cell);
});
assert_eq!(taker.await, None);Sourcepub fn get_weak(self: &Arc<Self>) -> GetWeak<T> ⓘwhere
T: Clone,
pub fn get_weak(self: &Arc<Self>) -> GetWeak<T> ⓘwhere
T: Clone,
Like get but creates a weak reference to self.
If self is dropped, the returned future will resolve to None.
use async_cell::sync::AsyncCell;
let cell = AsyncCell::<i32>::shared();
let getter = cell.get_weak();
spawn(async move {
cell.set(43); // any current value will be dropped
drop(cell);
});
assert_eq!(getter.await, None);