Struct Cached

Source
pub struct Cached<T, E> { /* private fields */ }
Expand description

The main struct implementing the async computation coalescing.

T is the value type and E is the error type of the computation.

A Cached computation is in one of three states:

  • There is no cached value and no inflight computation is happening
  • There is a cached value and no inflight computation is happening
  • There is no cached value, but an inflight computation is currently computing one

The Cached instance can be shared via cloning as it uses an Arc internally.

Cached::get_or_compute will

  • Start a new inflight computation if there is no cached value and no inflight computation is happening
  • Return the cached value immediately if there is a cached value available
  • Subscribe to an inflight computation if there is one happening and return the result of that when it concludes

The cache can be invalidated using Cached::invalidate

The instances of T and E are cloned for every time a user requests a value or gets handed an error E. Thus, consider using an Arc for expensive to clone variants of T and E.

The cached value is stored on the stack, so you may want to consider using a Box for large T.

Implementations§

Source§

impl<T, E> Cached<T, E>

Source

pub fn new() -> Self

Creates a new instance with no cached value present.

Source

pub fn new_with_value(value: T) -> Self

Creates a new instance with the given value in the cache.

Source

pub fn invalidate(&self) -> Option<T>

Invalidates the cache immediately, returning its value without cloning if present.

Source

pub fn is_inflight(&self) -> bool

Returns true iff there is an inflight computation happening.

Source

pub fn inflight_waiting_count(&self) -> usize

Returns the amount of instances waiting on an inflight computation, including the instance that started the computation.

Source

pub fn abort(&self) -> bool

Aborts the current inflight computation. Returns true iff there was an inflight computation to abort.

After this function returns, the instance will immediately act like there is no inflight computation happening. However, it might still take some time until the actual inflight computation finishes aborting.

Source

pub fn is_value_cached(&self) -> bool

Returns true iff a value is currently cached.

Source§

impl<T: Clone, E> Cached<T, E>

Source

pub fn get(&self) -> Option<T>

Returns the value of the cache immediately if present, cloning the value.

Source§

impl<T, E> Cached<T, E>
where T: Clone, E: Clone,

Source

pub async fn get_or_compute<Fut>( &self, computation: impl FnOnce() -> Fut, ) -> Result<T, Error<E>>
where Fut: Future<Output = Result<T, E>>,

This function will

  • Execute computation and the Future it returns if there is no cached value and no inflight computation is happening, starting a new inflight computation and returning the result of that
  • Not do anything with computation and return the cached value immediately if there is a cached value available
  • Not do anything with computation and subscribe to an inflight computation if there is one happening and return the result of that when it concludes

Note that the Future computation returns will not be executed via [tokio::spawn] or similar, but rather will become part of the Future this function returns. This means it does not need to be Send.

§Errors

If the inflight computation this function subscribed to or started returns an error, that error is cloned and returned by this function in an Error::Computation.

If this function does not start a computation, but subscribes to a computation which panics or gets dropped/cancelled, it will return an Error::Broadcast.

If this function starts a computation or subscribes to a computation that gets aborted with Cached::abort, it will return an Error::Aborted.

§Panics

This function panics if computation gets executed and panics, or if the Future returned by computation panics.

Source

pub async fn get_or_subscribe(&self) -> Option<Result<T, Error<E>>>

This function will

  • Return immediately with the cached value if a cached value is present
  • Return None immediately if no cached value is present and no inflight computation is happening
  • Subscribe to an inflight computation if there is one happening and return the result of that when it concludes
§Errors

If the inflight computation this function subscribed to returns an error, that error is cloned and returned by this function in an Error::Computation.

If this function subscribes to a computation which panics or gets dropped/cancelled, it will return an Error::Broadcast.

If this function subscribes to a computation that gets aborted with Cached::abort, it will return an Error::Aborted.

Source

pub async fn subscribe_or_recompute<Fut>( &self, computation: impl FnOnce() -> Fut, ) -> (Option<T>, Result<T, Error<E>>)
where Fut: Future<Output = Result<T, E>>,

This function will

  • Invalidate the cache and execute computation and the Future it returns if no inflight computation is happening, starting a new inflight computation and returning the result of that
  • Subscribe to an inflight computation if there is one happening and return the result of that when it concludes

Note that after calling this function, the cache will always be empty, even if the computation results in an error.

This function will return the previously cached value as well as the result of the computation it starts or subscribes to.

§Errors

If the inflight computation this function starts or subscribes to returns an error, that error is cloned and returned by this function in an Error::Computation.

If this function subscribes to a computation which panics or gets dropped/cancelled, it will return an Error::Broadcast.

If this function subscribes to or starts a computation that gets aborted with Cached::abort, it will return an Error::Aborted.

§Panics

This function panics if computation gets executed and panics, or if the Future returned by computation panics.

Source

pub async fn force_recompute<Fut>( &self, computation: Fut, ) -> (CachedState<T>, Result<T, Error<E>>)
where Fut: Future<Output = Result<T, E>>,

This function will invalidate the cache, potentially abort the inflight request if one is happening, and start a new inflight computation, returning the result of that.

It will return the previous CachedState as well as the result of the computation it starts.

§Errors

If the inflight computation this function starts returns an error, that error is cloned and returned by this function in an Error::Computation.

If this function starts a computation which panics or gets dropped/cancelled, it will return an Error::Broadcast.

If this function starts a computation that gets aborted with Cached::abort, it will return an Error::Aborted.

§Panics

This function panics if computation or the Future returned by computation panics.

Trait Implementations§

Source§

impl<T, E> Clone for Cached<T, E>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug, E: Debug> Debug for Cached<T, E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Default, E: Default> Default for Cached<T, E>

Source§

fn default() -> Cached<T, E>

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T, E> Freeze for Cached<T, E>

§

impl<T, E> !RefUnwindSafe for Cached<T, E>

§

impl<T, E> Send for Cached<T, E>
where T: Send, E: Send,

§

impl<T, E> Sync for Cached<T, E>
where T: Send, E: Send,

§

impl<T, E> Unpin for Cached<T, E>

§

impl<T, E> !UnwindSafe for Cached<T, E>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.