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}