umbral-cache 0.0.1

Pluggable cache backend for umbral. In-memory, SQLite, and Redis backends, plus view-level cache_page middleware.
Documentation

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 via redis::aio::ConnectionManager. Handles reconnect transparently.
  • [cache_page] — tower [Layer] that caches full GET/HEAD responses. Only status 200 is cached; skips when Cache-Control: no-store or Set-Cookie appears on the response.
  • [CachePlugin] — empty Plugin impl so other plugins can name "cache" as a dependency.

Deferred past v0

  • get_or_set helper that fills on miss inside a single round-trip.
  • Versioned keys + incr/decr atomic 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.