import "github.com/altessa-s/go-atlas/data/cache"Package cache provides a unified caching interface with multiple backends and serialization support. Features automatic fallback with singleflight
deduplication (prevents cache stampede), configurable TTL, and pluggable serializers (JSON, MessagePack, Protobuf).
| Option | Default | Description |
|---|---|---|
WithTtl |
1h | Default time-to-live for cache items |
WithSerializer |
JSON | Serialization format |
WithKeyNamespace |
none | Per-context namespace for tenant/subject isolation (see below) |
The cache key is the only isolation boundary: it is used both for the backend store and for singleflight de-duplication.
If two callers build the same bare key, they share the same cache entry and can collapse onto the same in-flight
GetWithFallback — so one caller may receive another's freshly computed value. In a multi-tenant service this is a
cross-tenant data leak.
Contract: in a multi-tenant deployment, keys must be scoped to the tenant/subject. Either include the tenant in every key
you pass, or configure WithKeyNamespace so the cache prefixes every operation automatically:
c := cache.New(provider, cache.WithKeyNamespace(func(ctx context.Context) string {
return principal.FromContext(ctx).Tenant() // "" disables prefixing (backward-compatible default)
}))WithKeyNamespace is applied uniformly to Get, Save, Exists, Delete, DeleteMany, and both the backend and
singleflight key inside GetWithFallback, so a Get and its matching Save always agree. Returning "" leaves keys
unchanged, so existing single-tenant callers are unaffected.
| Package | Description |
|---|---|
| factory | Configuration-based cache creation |
| lru | Generic thread-safe LRU cache |
| providers/freecache | Zero-GC in-memory provider |
| providers/lru | In-memory LRU provider |
| providers/noop | No-op provider for testing |
| providers/redis | Distributed Redis provider |