Struct ultra_batch::BatchFetcher

source ·
pub struct BatchFetcher<F>
where F: Fetcher,
{ /* private fields */ }
Expand description

Batches and caches loads from some datastore. A BatchFetcher can be used with any type that implements Fetcher. BatchFetchers are asynchronous and designed to be passed and shared between threads or tasks. Cloning a BatchFetcher is shallow and will use the same Fetcher.

BatchFetcher is designed primarily around batching database lookups– for example, fetching a user from a user ID, where a signle query to retrieve 50 users by ID is significantly faster than 50 separate queries to look up the same set of users.

A BatchFetcher is designed to be ephemeral. In the context of a web service, this means callers should most likely create a new BatchFetcher for each request, and not a BatchFetcher shared across multiple requests. BatchFetchers have no concept of cache invalidation, so old values are stored indefinitely (which means callers may get stale data or may exhaust memory endlessly).

BatchFetchers introduce a small amount of latency for loads. Each time a BatchFetcher receives a key to fetch that hasn’t been cached (or a set of keys), it will first wait for more keys to build a batch. The load will only trigger after a timeout is reached or once enough keys have been queued in the batch. See BatchFetcherBuilder for options to tweak latency and batch sizes.

See also BatchExecutor for a more general type designed primarly for mutations, but can also be used for fetching with more control over how batches are fetched.

§Load semantics

If the underlying Fetcher returns an error during the batch request, then all pending load and load_many requests will fail. Subsequent calls to load or load_many with the same keys will retry.

If the underlying Fetcher succeeds but does not return a value for a given key during a batch request, then the BatchFetcher will mark that key as “not found” and an error value of NotFound will be returned to all pending load and load_many requests. The “not found” status will be preserved, so subsequent calls with the same key will fail and will not retry.

Implementations§

source§

impl<F> BatchFetcher<F>
where F: Fetcher + Send + Sync + 'static,

source

pub fn build(fetcher: F) -> BatchFetcherBuilder<F>

Create a new BatchFetcher that uses the given Fetcher to retrieve data. Returns a BatchFetcherBuilder, which can be used to customize the BatchFetcher. Call .finish() to create the BatchFetcher.

§Examples

Creating a BatchFetcher with default options:

let user_fetcher = UserFetcher::new(db_conn);
let batch_fetcher = BatchFetcher::build(user_fetcher).finish();

Creating a BatchFetcher with custom options:

let user_fetcher = UserFetcher::new(db_conn);
let batch_fetcher = BatchFetcher::build(user_fetcher)
    .eager_batch_size(Some(50))
    .delay_duration(tokio::time::Duration::from_millis(5))
    .finish();
source

pub async fn load(&self, key: F::Key) -> Result<F::Value, LoadError>

Load the value with the associated key, either by calling the Fetcher or by loading the cached value. Returns an error if the value could not be loaded or if a value for the given key was not found.

See the type-level docs for BatchFetcher for more detailed loading semantics.

source

pub async fn load_many( &self, keys: &[F::Key] ) -> Result<Vec<F::Value>, LoadError>

Load all the values for the given keys, either by calling the Fetcher or by loading cached values. Values are returned in the same order as the input keys. Returns an error if any load fails.

See the type-level docs for BatchFetcher for more detailed loading semantics.

Trait Implementations§

source§

impl<F> Clone for BatchFetcher<F>
where F: Fetcher,

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<F> Freeze for BatchFetcher<F>

§

impl<F> !RefUnwindSafe for BatchFetcher<F>

§

impl<F> Send for BatchFetcher<F>

§

impl<F> Sync for BatchFetcher<F>

§

impl<F> Unpin for BatchFetcher<F>

§

impl<F> !UnwindSafe for BatchFetcher<F>

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> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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,

§

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>,

§

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>,

§

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.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> Erased for T