pub trait CompositionWritePolicy: Send + Sync {
// Required method
fn execute_with<'life0, 'life1, 'async_trait, F1, F2, Fut1, Fut2, O>(
&'life0 self,
key: CacheKey,
write_l1: F1,
write_l2: F2,
offload: &'life1 O,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>
where F1: FnOnce(CacheKey) -> Fut1 + Send + 'async_trait,
F2: FnOnce(CacheKey) -> Fut2 + Send + 'async_trait,
Fut1: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
Fut2: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
O: Offload<'static> + 'async_trait,
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait;
}Expand description
Policy trait for controlling write operations across cache layers.
This trait encapsulates the control flow strategy (sequential, parallel, conditional)
for writing to multiple cache layers, while delegating the actual write operations
to provided closures. This design allows the same policy to be used at both the
CacheBackend level (typed data) and Backend level (raw bytes).
§Type Parameters
The policy is generic over:
E- The error type (e.g.,BackendError)F1, F2- Closures for writing to L1 and L2O- The offload type for background task execution
§Example
use hitbox_backend::composition::policy::CompositionWritePolicy;
let policy = SequentialWritePolicy::default();
// Use with CacheBackend level
policy.execute_with(
key.clone(),
|k| async { l1.set::<User>(&k, value, ttl).await },
|k| async { l2.set::<User>(&k, value, ttl).await },
&offload,
).await?;Required Methods§
Sourcefn execute_with<'life0, 'life1, 'async_trait, F1, F2, Fut1, Fut2, O>(
&'life0 self,
key: CacheKey,
write_l1: F1,
write_l2: F2,
offload: &'life1 O,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
F1: FnOnce(CacheKey) -> Fut1 + Send + 'async_trait,
F2: FnOnce(CacheKey) -> Fut2 + Send + 'async_trait,
Fut1: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
Fut2: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
O: Offload<'static> + 'async_trait,
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn execute_with<'life0, 'life1, 'async_trait, F1, F2, Fut1, Fut2, O>(
&'life0 self,
key: CacheKey,
write_l1: F1,
write_l2: F2,
offload: &'life1 O,
) -> Pin<Box<dyn Future<Output = Result<(), BackendError>> + Send + 'async_trait>>where
F1: FnOnce(CacheKey) -> Fut1 + Send + 'async_trait,
F2: FnOnce(CacheKey) -> Fut2 + Send + 'async_trait,
Fut1: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
Fut2: Future<Output = Result<(), BackendError>> + Send + 'static + 'async_trait,
O: Offload<'static> + 'async_trait,
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Execute a write operation with custom write closures for each layer.
The policy determines the control flow (when and how to call the closures), while the closures handle the actual writing and any pre-processing (like serialization or validation).
§Arguments
key- The cache key to write (owned for'staticfutures)write_l1- Closure that writes to L1write_l2- Closure that writes to L2offload- Offload manager for spawning background tasks (e.g., losing race futures)
§Returns
Success if the policy’s success criteria are met. Different policies have different success criteria (e.g., both must succeed, or at least one must succeed).
§Generic Parameters
F1, F2- Closures for writing to L1 and L2 that returnBackendResult<()>O- The offload type for background task execution
§Error Handling
When both layers fail, implementations should preserve both errors in a
CompositionError::BothLayersFailed for better debugging.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.