pub struct BatchExecutor<E>where
E: Executor,{ /* private fields */ }Expand description
Batches calls to an Executor, such as for bulk inserting, updating,
or deleting records in a datastore. BatchExecutors are asynchronous
and designed to be passed and shared between threads or tasks. Cloning
a BatchExecutor is shallow and will use the same underlying Executor.
BatchExecutor is designed primarily for bulk database operations– for
example, inserting lots of records, where a single query to insert
50 new records is much faster than 50 separate queries. However, it can
be used for fetching data or any other bulk operation as well.
Unlike BatchFetcher, BatchExecutor has no
concepts of keys, values, deduplication, or caching; each executed value
is passed directly to the underlying Executor. As such, it could also
be suitable for writing a custom caching layer in situations where
BatchFetcher is not suitable.
BatchExecutors introduce a small amount of latency for executions. Each
time a new value or set of values is sent for execution, it will first
wait for more values to buid a batch. The execution will only trigger after
a timeout is reached or once enough values have been queued in the batch.
See BatchExecutorBuilder for options to tweak latency and batch sizes.
§Execution semantics
If the underlying Executor returns an error during the batch execution,
then all pending execute and execute_many
requests will fail. The same values can be resubmitted to retry.
If the underlying Executor succeeds but does not return a Vec that
contains results for all values, then calls to execute
may return None. Calls to execute_many
may return a Vec containing less output values than input values.
Implementations§
Source§impl<E> BatchExecutor<E>
impl<E> BatchExecutor<E>
Sourcepub fn build(executor: E) -> BatchExecutorBuilder<E>
pub fn build(executor: E) -> BatchExecutorBuilder<E>
Create a new BatchExecutor athat uses the given Executor to
execute values. Returns a BatchExecutorBuilder, which can be
used to customize the BatchExecutor. Call .finish()
to create the BatchExecutor.
§Examples
Creating a BatchExecutor with default options:
let user_inserter = UserInserter::new(db_conn);
let batch_inserter = BatchExecutor::build(user_inserter).finish();Creating a BatchExecutor with custom options:
let user_inserter = UserInserter::new(db_conn);
let batch_inserter = BatchExecutor::build(user_inserter)
.eager_batch_size(Some(50))
.delay_duration(tokio::time::Duration::from_millis(5))
.finish();Sourcepub async fn execute(
&self,
key: E::Value,
) -> Result<Option<E::Result>, ExecuteError>
pub async fn execute( &self, key: E::Value, ) -> Result<Option<E::Result>, ExecuteError>
Submit a value to be executed by the Executor. Returns the
result value returned by the Executor for this given item. See
the type-level docs for BatchExecutor for
detailed execution semantics.
Sourcepub async fn execute_many(
&self,
values: Vec<E::Value>,
) -> Result<Vec<E::Result>, ExecuteError>
pub async fn execute_many( &self, values: Vec<E::Value>, ) -> Result<Vec<E::Result>, ExecuteError>
Submit multiple values to be executed by the Executor. Returns a
Vec containg values for each result returned by the Executor
for each given input value (but note that the returned Vec may
not have values for all inputs if the Executor did not return
enough results). See the type-level docs for BatchExecutor
for detailed execution semantics.