Skip to main content

CompositionWritePolicy

Trait CompositionWritePolicy 

Source
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 L2
  • O - 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§

Source

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 'static futures)
  • write_l1 - Closure that writes to L1
  • write_l2 - Closure that writes to L2
  • offload - 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 return BackendResult<()>
  • 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.

Implementors§