Crate hitbox_actix[−][src]
Expand description
Hitbox-Actix
Hitbox-Actix is an asynchronous caching framework for Actix actor framework. It’s designed for distributed and for single-machine applications.
Features
- Automatic cache key generation.
- Multiple cache backend implementations.
- Stale cache mechanics.
- Cache locks for dogpile effect preventions.
- Distributed cache locks.
- Detailed metrics out of the box.
Backend implementations:
- Redis
- In-memory backend
Feature flags
- derive - Support for Cacheable trait derive macros.
- redis - Support for default redis backend.
Restrictions
Default cache key implementation based on serde_qs crate and have some restrictions.
Documentation
Flow diagrams:
Example
Dependencies:
[dependencies]
hitbox_actix = "0.1"
Code:
First, you should derive Cacheable trait for your actix Message:
use actix::prelude::*; use actix_derive::{Message, MessageResponse}; use hitbox_actix::prelude::*; use serde::{Deserialize, Serialize}; #[derive(Message, Cacheable, Serialize)] #[rtype(result = "Result<Pong, Error>")] struct Ping { id: i32, } #[derive(MessageResponse, Deserialize, Serialize, Debug)] struct Pong(i32); #[derive(Debug)] struct Error;
Next step is declare Upstream actor and implement actix Handler for Ping:
#[derive(Debug)] struct UpstreamActor; impl Actor for UpstreamActor { type Context = Context<Self>; } impl Handler<Ping> for UpstreamActor { type Result = ResponseFuture<<Ping as Message>::Result>; fn handle(&mut self, msg: Ping, _ctx: &mut Self::Context) -> Self::Result { println!("Handler::Ping"); Box::pin(async move { actix_rt::time::sleep(core::time::Duration::from_secs(3)).await; Ok(Pong(msg.id)) }) } }
The last step is initialize and start CacheActor and UpstreamActor:
use tracing_subscriber::EnvFilter; #[actix_rt::main] async fn main() -> Result<(), CacheError> { let filter = EnvFilter::new("hitbox=trace"); tracing_subscriber::fmt() .with_max_level(tracing::Level::TRACE) .with_env_filter(filter) .init(); let backend = RedisBackend::new() .await? .start(); let cache = Cache::builder() .with_stale() .finish(backend) .start(); let upstream = UpstreamActor.start(); /// And send `Ping` message into cache actor let msg = Ping { id: 42 }; let res = cache.send(msg.into_cache(&upstream)).await??; println!("{:#?}", res); Ok(()) }
Re-exports
pub use actor::CacheActor; | |
pub use builder::CacheBuilder; | |
pub use messages::IntoCache; | |
pub use messages::QueryCache; | |
pub use runtime::ActixAdapter; |
Modules
actor | Cache actor and Builder. |
builder | CacheActor builder patter implementation. |
handlers | Actix Handler |
messages | QueryCache message declaration and converting. |
prelude | Prelude for hitbox_actix. |
runtime | hitbox::runtime::RuntimeAdapter implementation for Actix runtime. |
Structs
RedisBackend | Redis cache backend based on redis-rs crate. |
Enums
CacheError | Base hitbox error. |
Traits
Cacheable | Trait describes cache configuration per type that implements this trait. |
Type Definitions
Cache | Default type alias with RedisBackend. You can disable it or define it manually in your code. |
Derive Macros
Cacheable | Derive Cacheable macro implementation. |