DataController

Trait DataController 

Source
pub trait DataController:
    Sized
    + Send
    + Sync
    + 'static {
    type Key: Debug + Display + Hash + Clone + Eq + Sized + Send + Sync + 'static;
    type Value: Debug + Clone + Send + Sync + 'static;
    type CacheUpdate: Debug + Send + Sync + 'static;
    type Error: Display + Debug + Send + Sync + 'static;

    // Required methods
    fn get_for_key<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 Self::Key,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Self::Value>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait;
    fn write_back<'life0, 'async_trait>(
        &'life0 self,
        updates: Arc<UpdateIterator<Self>>,
    ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait;
    fn on_new<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 Self::Key,
        value: &'life2 Self::Value,
    ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn on_delete<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 Self::Key,
        update: Option<&'life2 Self::CacheUpdate>,
    ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn on_change<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        key: &'life1 Self::Key,
        value: &'life2 Self::Value,
        old_value: Self::Value,
        prev_handler: Option<Self::CacheUpdate>,
    ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait;
    fn primary_key_of(&self, value: &Self::Value) -> Self::Key;

    // Provided methods
    fn secondary_keys_of(&self, _value: &Self::Value) -> Vec<Self::Key> { ... }
    fn get_primary_key_for<'life0, 'life1, 'async_trait>(
        &'life0 self,
        key: &'life1 Self::Key,
    ) -> Pin<Box<dyn Future<Output = Result<Option<Self::Key>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait { ... }
    fn is_primary(&self, _key: &Self::Key) -> bool { ... }
    fn on_access<'life0, 'life1, 'life2, 'async_trait>(
        &'life0 self,
        _key: &'life1 Self::Key,
        _value: &'life2 Self::Value,
        prev_update: Option<Self::CacheUpdate>,
    ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
       where Self: 'async_trait,
             'life0: 'async_trait,
             'life1: 'async_trait,
             'life2: 'async_trait { ... }
}
Expand description

The data controller implementation.

Use of the Cache must start with creating a type that implements this trait.

This crate includes example implementations of data controllers in the simulation code. These can be found in the test::simulation::db::entity module as the Manager types. Since they all use the same backend (SeaORM framework), they implement the trait DCCommon which provides a set of common methods for simulation data controllers.

Required Associated Types§

Source

type Key: Debug + Display + Hash + Clone + Eq + Sized + Send + Sync + 'static

The key type to be used with methods like Cache::get() or Cache::entry().

To implement multi-key access you can use an enum as the key type. See, for example, CustomerBy key type in the supplied simulation code.

Source

type Value: Debug + Clone + Send + Sync + 'static

The record type to be stored in the cache and maintained by the data controller.

Source

type CacheUpdate: Debug + Send + Sync + 'static

The type of the update pool records that are produced by the data controller.

The simulation code uses the CacheUpdates enum for this purpose. Then, every every model’s data controller uses this enum with respective active model type. See the implemenation for the customer model for example.

Source

type Error: Display + Debug + Send + Sync + 'static

The error type that the data controller can return. Note that this is the only error type the the cache controller is using!

Required Methods§

Source

fn get_for_key<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 Self::Key, ) -> Pin<Box<dyn Future<Output = Result<Option<Self::Value>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Must return the value for the given key, if it exists, None otherwise.

Example: customer model.

Source

fn write_back<'life0, 'async_trait>( &'life0 self, updates: Arc<UpdateIterator<Self>>, ) -> Pin<Box<dyn Future<Output = Result<(), Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait,

Given a list of update records, must apply these updates to the underlying backend.

Example: DCCommon::wbdc_write_back().

Source

fn on_new<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 Self::Key, value: &'life2 Self::Value, ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Called when a new record is added to the cache. On success, it must return a DataControllerResponse with the operation type set to what the data controller considers appropriate for the new record. For example, if it is known that the new record will have exactly the same field values after being written to the backend as it had when submitted to this method, then the operation can be set to DataControllerOp::Insert.

Example: DCCommon::wbdbc_on_new(). The trait classifies DB models into two categories: immutable and mutable. Immutable models do not modify written records (e.g., when there is no primary key autoincrement) and their records are immediately cached without a roundtrip to the database.

Source

fn on_delete<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 Self::Key, update: Option<&'life2 Self::CacheUpdate>, ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Called when there is a delete request for the given key has been received. Don’t mix it up with the invalidate request which is only clearing a cache entry.

The most typical response operation for this method is DataControllerOp::Revoke.

Example: DCCommon::wbdc_on_delete().

Source

fn on_change<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, key: &'life1 Self::Key, value: &'life2 Self::Value, old_value: Self::Value, prev_handler: Option<Self::CacheUpdate>, ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

Called when a record is modified by the user.

Example: DCCommon::wbdc_on_change().

Source

fn primary_key_of(&self, value: &Self::Value) -> Self::Key

Returns the primary key for the given value.

Example: customer model.

Provided Methods§

Source

fn secondary_keys_of(&self, _value: &Self::Value) -> Vec<Self::Key>

Returns a list of secondary keys for the given value. Default implementation returns an empty vector.

Example: customer model.

Source

fn get_primary_key_for<'life0, 'life1, 'async_trait>( &'life0 self, key: &'life1 Self::Key, ) -> Pin<Box<dyn Future<Output = Result<Option<Self::Key>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait,

Take a key and return its corresponding primary key. This operation may require a backend request.

The default implementation covers the simple case where there are no secondary keys, simply returning the key itself.

Example: customer model.

Source

fn is_primary(&self, _key: &Self::Key) -> bool

Returns true if the given key is considered the primary key.

The default implementation always returns true, which is appropriate when no secondary keys exist.

Example: customer model.

Source

fn on_access<'life0, 'life1, 'life2, 'async_trait>( &'life0 self, _key: &'life1 Self::Key, _value: &'life2 Self::Value, prev_update: Option<Self::CacheUpdate>, ) -> Pin<Box<dyn Future<Output = Result<DataControllerResponse<Self>, Self::Error>> + Send + 'async_trait>>
where Self: 'async_trait, 'life0: 'async_trait, 'life1: 'async_trait, 'life2: 'async_trait,

This method is called on every access to the given key in the cache. It can be used to implement various related functionality like updateing the access time column in the backend, or calculating related metrics or statistics.

The default implementation does nothing and returns a no-op response.

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§

Source§

impl<DBCP> DataController for wb_cache::test::simulation::db::entity::customer::Manager<DBCP>
where DBCP: DBProvider,

Source§

impl<DBCP> DataController for wb_cache::test::simulation::db::entity::inventory_record::Manager<DBCP>
where DBCP: DBProvider,

Source§

impl<DBCP> DataController for wb_cache::test::simulation::db::entity::order::Manager<DBCP>
where DBCP: DBProvider,

Source§

impl<DBCP> DataController for wb_cache::test::simulation::db::entity::product::Manager<DBCP>
where DBCP: DBProvider,

Source§

impl<DBCP> DataController for wb_cache::test::simulation::db::entity::session::Manager<DBCP>
where DBCP: DBProvider,