quick_cache
quick_cache
is a lightweight and high performance concurrent cache optimized for low cache overhead. The http-cache-quickcache
implementation provides traditional buffered caching capabilities.
Getting Started
The quick_cache
backend cache manager is provided by the http-cache-quickcache
crate.
cargo add http-cache-quickcache
Basic Usage with Tower
The quickcache manager works excellently with Tower services:
#![allow(unused)] fn main() { use tower::{Service, ServiceExt}; use http::{Request, Response, StatusCode}; use http_body_util::Full; use bytes::Bytes; use http_cache_quickcache::QuickManager; use std::convert::Infallible; // Example Tower service that uses QuickManager for caching #[derive(Clone)] struct CachingService { cache_manager: QuickManager, } impl Service<Request<Full<Bytes>>> for CachingService { type Response = Response<Full<Bytes>>; type Error = Box<dyn std::error::Error + Send + Sync>; type Future = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self::Response, Self::Error>> + Send>>; fn poll_ready(&mut self, _cx: &mut std::task::Context<'_>) -> std::task::Poll<Result<(), Self::Error>> { std::task::Poll::Ready(Ok(())) } fn call(&mut self, req: Request<Full<Bytes>>) -> Self::Future { let manager = self.cache_manager.clone(); Box::pin(async move { // Cache logic using the manager would go here let response = Response::builder() .status(StatusCode::OK) .body(Full::new(Bytes::from("Hello from cached service!")))?; Ok(response) }) } } }
Working with the manager directly
First construct your manager instance. This example will use the default cache configuration.
#![allow(unused)] fn main() { let manager = Arc::new(QuickManager::default()); }
You can also specify other configuration options. This uses the new
methods on both QuickManager
and quick_cache::sync::Cache
to construct a cache with a maximum capacity of 100 items.
#![allow(unused)] fn main() { let manager = Arc::new(QuickManager::new(quick_cache::sync::Cache::new(100))); }
Traditional Cache Operations
You can attempt to retrieve a record from the cache using the get
method. This method accepts a &str
as the cache key and returns an Result<Option<(HttpResponse, CachePolicy)>, BoxError>
.
#![allow(unused)] fn main() { let response = manager.get("my-cache-key").await?; }
You can store a record in the cache using the put
method. This method accepts a String
as the cache key, a HttpResponse
as the response, and a CachePolicy
as the policy object. It returns an Result<HttpResponse, BoxError>
. The below example constructs the response and policy manually, normally this would be handled by the middleware.
#![allow(unused)] fn main() { let url = Url::parse("http://example.com")?; let response = HttpResponse { body: TEST_BODY.to_vec(), headers: Default::default(), status: 200, url: url.clone(), version: HttpVersion::Http11, }; let req = http::Request::get("http://example.com").body(())?; let res = http::Response::builder() .status(200) .body(TEST_BODY.to_vec())?; let policy = CachePolicy::new(&req, &res); let response = manager.put("my-cache-key".into(), response, policy).await?; }
You can remove a record from the cache using the delete
method. This method accepts a &str
as the cache key and returns an Result<(), BoxError>
.
#![allow(unused)] fn main() { manager.delete("my-cache-key").await?; }