hitbox_actix/
builder.rs

1//! CacheActor builder patter implementation.
2use crate::CacheActor;
3use actix::{Actor, Addr};
4use hitbox::settings::{CacheSettings, Status};
5use hitbox_backend::Backend;
6use std::marker::PhantomData;
7
8/// Cache actor configurator.
9///
10/// # Example
11/// ```rust
12/// use actix::prelude::*;
13/// use hitbox_actix::{Cache, RedisBackend, CacheError};
14///
15/// #[actix_rt::main]
16/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
17///     let backend = RedisBackend::new()
18///         .await?
19///         .start();
20///     let cache = Cache::builder()
21///         .enable()
22///         .finish(backend)
23///         .start();
24///     Ok(())
25/// }
26/// ```
27pub struct CacheBuilder<B>
28where
29    B: Backend + Actor,
30{
31    settings: CacheSettings,
32    _p: PhantomData<B>,
33}
34
35impl<B> Default for CacheBuilder<B>
36where
37    B: Backend,
38{
39    fn default() -> Self {
40        CacheBuilder {
41            settings: CacheSettings {
42                cache: Status::Enabled,
43                stale: Status::Enabled,
44                lock: Status::Disabled,
45            },
46            _p: PhantomData::default(),
47        }
48    }
49}
50
51impl<B> CacheBuilder<B>
52where
53    B: Backend,
54{
55    /// Enable interaction with cache backend. (Default value).
56    pub fn enable(mut self) -> Self {
57        self.settings.cache = Status::Enabled;
58        self
59    }
60
61    /// Disable interaction with cache backend.
62    ///
63    /// All messages sent to disabled Cache actor passed directly to an upstream actor.
64    pub fn disable(mut self) -> Self {
65        self.settings.cache = Status::Disabled;
66        self
67    }
68
69    /// Enable stale cache mechanics. (Default value).
70    ///
71    /// If [CacheActor] receives a stale value, it does not return it immediately.
72    /// It polls data from upstream, and if the upstream returned an error,
73    /// the [CacheActor] returns a stale value. If no error occurred in the upstream,
74    /// then a fresh value is stored in the cache and returned.
75    pub fn with_stale(mut self) -> Self {
76        self.settings.stale = Status::Enabled;
77        self
78    }
79
80    /// Disable stale cache mechanics.
81    pub fn without_stale(mut self) -> Self {
82        self.settings.stale = Status::Disabled;
83        self
84    }
85
86    /// Enable cache lock mechanics.
87    ///
88    /// Prevents multiple upstream requests for the same cache key in case of cache data is missing.
89    /// Only the first request will produce an upstream request.
90    /// The remaining requests wait for a first upstream response and return updated data.
91    /// If `with_stale` is enabled the remaining requests don't wait for an upstream response
92    /// and return stale cache data if it exists.
93    pub fn with_lock(mut self) -> Self {
94        self.settings.lock = Status::Enabled;
95        self
96    }
97
98    /// Disable cache lock mechanics. (Default value).
99    pub fn without_lock(mut self) -> Self {
100        self.settings.lock = Status::Disabled;
101        self
102    }
103
104    /// Instantiate new [Cache] instance with current configuration and passed backend.
105    ///
106    /// Backend is an [Addr] of actix [Actor] which implements [Backend] trait:
107    ///
108    /// [Cache]: crate::Cache
109    /// [Backend]: hitbox_backend::Backend
110    /// [Addr]: https://docs.rs/actix/latest/actix/prelude/struct.Addr.html
111    /// [Actor]: https://docs.rs/actix/latest/actix/prelude/trait.Actor.html
112    /// [Messages]: https://docs.rs/actix/latest/actix/prelude/trait.Message.html
113    /// [Handler]: https://docs.rs/actix/latest/actix/prelude/trait.Handler.html
114    pub fn finish(self, backend: Addr<B>) -> CacheActor<B> {
115        CacheActor {
116            settings: self.settings,
117            backend,
118        }
119    }
120}