Hitbox-Actix is an asynchronous caching framework for [Actix] actor framework. It's designed for distributed and for single-machine applications.
## Features - [x] Automatic cache key generation. - [x] Multiple cache backend implementations. - [x] Stale cache mechanics. - [ ] Cache locks for [dogpile effect] preventions. - [ ] Distributed cache locks. - [ ] Detailed metrics out of the box.
[ ] In-memory backend
Default cache key implementation based on serde_qs crate and have some restrictions.
toml
[dependencies]
hitbox_actix = "0.1"
First, you should derive [Cacheable] trait for your actix [Message]:
```rust use actix::prelude::; use actix_derive::{Message, MessageResponse}; use hitbox_actix::prelude::; use serde::{Deserialize, Serialize};
struct Ping { id: i32, }
struct Pong(i32);
struct Error; ```
Next step is declare Upstream actor and implement actix Handler for Ping:
```rust
struct UpstreamActor;
impl Actor for UpstreamActor {
type Context = Context
impl Handler
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:
```rust use tracing_subscriber::EnvFilter;
async fn main() -> Result<(), CacheError> { let filter = EnvFilter::new("hitbox=trace"); tracingsubscriber::fmt() .withmaxlevel(tracing::Level::TRACE) .withenv_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(())
} ```