umbral-cache — pluggable cache for umbral.
Django's cache framework, the slice that matters for production:
a [Cache] handle over a [CacheBackend] trait, three built-in
backends (in-memory, SQLite, Redis), and a [cache_page] view
middleware that caches full GET responses, matching Django's
@cache_page decorator.
// Boot wiring (App::builder)
let cache = Cache::memory();
// … or for Redis in production:
// let cache = Cache::redis("redis://localhost:6379/0").await?;
CachePlugin::init(cache.clone());
// In a handler — explicit cache access
cache.set("homepage:html", &rendered, Some(Duration::from_secs(60))).await;
if let Some(html) = cache.get::<String>("homepage:html").await {
return Ok(Html(html));
}
// View-level caching (wraps a Router subtree)
use umbral_cache::cache_page;
let public = Router::new()
.route("/", get(home))
.layer(cache_page(Duration::from_secs(60)));
Surface
- [
CacheBackend] — the trait. Bytes in, bytes out, async. - [
CacheError] — unified error type for backends that can fail. - [
Cache] — the handle. Generic-over-T methods wrap the backend with serde encoding so callers traffic in their own types. - [
MemoryBackend] —tokio::sync::Mutex<HashMap>with per-key expiry. Lost on process exit. Default choice for development and single-process deployments. - [
SqliteBackend] — table-backed, durable across restarts. Expired rows are lazily skipped on read and cleared on a background pass when [SqliteBackend::sweep] is called. - [
RedisBackend] — (feature ="redis") production backend viaredis::aio::ConnectionManager. Handles reconnect transparently. - [
cache_page] — tower [Layer] that caches full GET/HEAD responses. Only status 200 is cached; skips whenCache-Control: no-storeorSet-Cookieappears on the response. - [
CachePlugin] — empty Plugin impl so other plugins can name "cache" as a dependency.
Deferred past v0
get_or_sethelper that fills on miss inside a single round-trip.- Versioned keys +
incr/decratomic ops. - Memcached backend.
- Distributed cache invalidation (tag-based).
- ETag / 304 conditional caching inside
cache_page— the current implementation always serves the cached body in full.