Skip to main content

Crate imc

Crate imc 

Source
Expand description

A trait-based, deduplicating, in-memory cache for Rust.

One data copy per unique identity, even when the same record is fetched through different query arguments.

use std::time::Duration;
use imc::{ImcCacheable, CacheStrategy, through_imc};

#[derive(Clone, Debug, PartialEq)]
struct User { id: u32, name: String }

impl ImcCacheable for User {
    type Id = u32;
    type Key = String;
    fn cache_id(&self) -> u32 { self.id }
    fn cache_strategy() -> CacheStrategy { CacheStrategy::Lru }
    fn cache_ttl() -> Option<Duration> { Some(Duration::from_secs(300)) }
    fn cache_max_size() -> usize { 10_000 }
}

let user: User = through_imc(42u32, || User { id: 42, name: "Alice".into() });
let same: User = through_imc("alice@example.com", || User { id: 42, name: "Alice".into() });
assert_eq!(user, same);

§Feature flags

FeatureDescription
(none)Core caching: through_imc, dedup, eviction, TTL
asyncEnables through_imc_async / through_imc_keyed_async (runtime-agnostic)
tokioImplies async + makes CacheWorker use tokio::task::spawn_blocking
invalidation-redisCross-process cache invalidation via Redis pub/sub
criticalCritical-key broadcast via Redis pub/sub. Implies invalidation-redis. Requires #[derive(CriticalKey)] on key enums used with through_imc_keyed
loggingStructured tracing events via log_event! macro
metrics-prometheusPrometheus counters/gauges + HTTP /metrics endpoint

§Quick start

  1. Add imc to Cargo.toml
[dependencies]
imc = "0.1"
  1. Implement ImcCacheable on your type
use std::time::Duration;
use imc::{ImcCacheable, CacheStrategy};

#[derive(Clone)]
struct User { id: u32, name: String }

impl ImcCacheable for User {
    type Id = u32;
    type Key = String;

    fn cache_id(&self) -> u32 { self.id }

    fn cache_strategy() -> CacheStrategy { CacheStrategy::Lru }
    fn cache_ttl() -> Option<Duration> { Some(Duration::from_secs(300)) }
    fn cache_max_size() -> usize { 10_000 }
}
  1. Cache expensive operations
let user: User = through_imc(42u32, || fetch_user(42));
let same: User = through_imc("alice@example.com", || fetch_user_by_email("alice"));
assert_eq!(user.id, same.id);

§Re-exports

The CriticalKey derive macro is provided by the imc-derive crate and re-exported here for convenience:

ⓘ
use imc::CriticalKey;

#[derive(Hash, Clone, CriticalKey)]
enum UserKey { ById(i32), ByEmail(String) }

Macros§

log_event
Emit a structured tracing event when the logging feature is enabled.

Structs§

CacheWorker
A background worker that periodically sweeps the cache for TTL-expired entries and evicts over-capacity namespaces, and processes remove/clear/shutdown commands.
Imc
Entry point for the imc cache system.
WorkerConfig
Configuration for the background maintenance worker.

Enums§

CacheStrategy
Eviction strategy for a per-type cache namespace.

Traits§

CriticalKeycritical
Marker trait for cache keys whose updates should be broadcast to other pods via Redis pub/sub.
ImcCacheable
Any type that should be cacheable must implement this trait.

Functions§

imc_clear
Evict every cached entry for T.
imc_invalidation_id
Compute the stable hash string that other pods must publish to invalidate this cache entry via Redis pub/sub.
imc_len
Number of unique entries currently cached for T.
imc_remove
Remove a single entry by its unique Id.
through_imc
Run a (usually expensive) closure f, caching its result.
through_imc_asyncasync or tokio
Async version of through_imc.
through_imc_keyed
Typed-key variant of through_imc.
through_imc_keyed_asyncasync or tokio
Typed-key variant of through_imc_async.

Derive Macros§

CriticalKeycritical