Documentation
¶
Overview ¶
Package cache is the kit's transport-agnostic key/value cache abstraction.
Implementations:
- NewMemory[V]() — in-process LRU-ish cache with TTL eviction
- (future) NewRedis[V](client, prefix) — Redis-backed adapter
Consumers code against Cache[V], pick an implementation at wiring time, and can swap memory ↔ Redis without touching call sites.
Index ¶
- Variables
- type Cache
- type Codec
- type JSONCodec
- type Memory
- func (m *Memory[V]) Clear(_ context.Context) error
- func (m *Memory[V]) Delete(_ context.Context, key string) error
- func (m *Memory[V]) Get(ctx context.Context, key string) (V, error)
- func (m *Memory[V]) GetOrLoad(ctx context.Context, key string, ttl time.Duration, ...) (V, error)
- func (m *Memory[V]) Len() int
- func (m *Memory[V]) Set(ctx context.Context, key string, value V, ttl time.Duration) error
- func (m *Memory[V]) SetClock(now func() time.Time)
- type Namespaced
- func (n *Namespaced[V]) Clear(ctx context.Context) error
- func (n *Namespaced[V]) Delete(ctx context.Context, key string) error
- func (n *Namespaced[V]) Get(ctx context.Context, key string) (V, error)
- func (n *Namespaced[V]) GetOrLoad(ctx context.Context, key string, ttl time.Duration, ...) (V, error)
- func (n *Namespaced[V]) Set(ctx context.Context, key string, value V, ttl time.Duration) error
- type Redis
- func (r *Redis[V]) Clear(ctx context.Context) error
- func (r *Redis[V]) Delete(ctx context.Context, key string) error
- func (r *Redis[V]) Get(ctx context.Context, key string) (V, error)
- func (r *Redis[V]) GetOrLoad(ctx context.Context, key string, ttl time.Duration, ...) (V, error)
- func (r *Redis[V]) Set(ctx context.Context, key string, value V, ttl time.Duration) error
- type RedisOption
- type Tiered
- func (t *Tiered[V]) Clear(ctx context.Context) error
- func (t *Tiered[V]) Delete(ctx context.Context, key string) error
- func (t *Tiered[V]) Get(ctx context.Context, key string) (V, error)
- func (t *Tiered[V]) GetOrLoad(ctx context.Context, key string, ttl time.Duration, ...) (V, error)
- func (t *Tiered[V]) Set(ctx context.Context, key string, value V, ttl time.Duration) error
Constants ¶
This section is empty.
Variables ¶
var ErrMiss = errors.New("cache: miss")
ErrMiss is returned by Get when the key is absent or has expired.
Functions ¶
This section is empty.
Types ¶
type Cache ¶
type Cache[V any] interface { Get(ctx context.Context, key string) (V, error) Set(ctx context.Context, key string, value V, ttl time.Duration) error Delete(ctx context.Context, key string) error // GetOrLoad fetches the cached value or calls loader on miss, storing the // result with ttl before returning. Concurrent loaders for the same key // are coalesced: only one loader runs, the rest wait for the result. GetOrLoad(ctx context.Context, key string, ttl time.Duration, loader func(ctx context.Context) (V, error)) (V, error) // Clear flushes the entire namespace. Clear(ctx context.Context) error }
Cache is the common interface backed by every implementation.
type JSONCodec ¶ added in v0.3.0
type JSONCodec[V any] struct{}
JSONCodec is the default Codec — encodes V via encoding/json.
type Memory ¶
type Memory[V any] struct { // contains filtered or unexported fields }
Memory is an in-process Cache[V] with TTL eviction and single-flight loading. Suitable for low-cardinality / latency-sensitive caches that don't need cross-instance sharing. Thread-safe.
type Namespaced ¶ added in v0.3.0
type Namespaced[V any] struct { // contains filtered or unexported fields }
Namespaced wraps any Cache[V] with a key prefix so multiple services (or multiple subsystems within one service) can share a physical Redis without colliding on keys.
The wrapped cache's Clear is delegated as-is — implementations are responsible for honouring the prefix internally. The Redis backend already does the right thing (SCAN under prefix); Memory's Clear flushes everything, which is fine for tests but means a Namespaced Memory shares its keyspace across namespaces.
func NewNamespaced ¶ added in v0.3.0
func NewNamespaced[V any](inner Cache[V], prefix string) *Namespaced[V]
NewNamespaced returns a wrapper that prepends prefix (followed by ":") to every key before delegating.
func (*Namespaced[V]) Clear ¶ added in v0.3.0
func (n *Namespaced[V]) Clear(ctx context.Context) error
func (*Namespaced[V]) Delete ¶ added in v0.3.0
func (n *Namespaced[V]) Delete(ctx context.Context, key string) error
func (*Namespaced[V]) Get ¶ added in v0.3.0
func (n *Namespaced[V]) Get(ctx context.Context, key string) (V, error)
type Redis ¶ added in v0.3.0
type Redis[V any] struct { // contains filtered or unexported fields }
Redis is a Cache[V] backed by go-redis. Values are JSON-encoded by default; supply WithCodec to pick a different format.
Concurrent loaders for the same key are coalesced in-process via a per-instance singleflight map. Cross-instance coalescing would need a Redis lock (SETNX) — out of scope for the kit-level abstraction; layer it on top when you need it.
func NewRedis ¶ added in v0.3.0
func NewRedis[V any](client redis.UniversalClient, opts ...RedisOption[V]) *Redis[V]
NewRedis returns a Cache[V] backed by client. The client is expected to be already configured (URL, auth, pool size); the cache doesn't own its lifecycle.
func (*Redis[V]) Clear ¶ added in v0.3.0
Clear removes every key under the configured prefix. Implemented via SCAN + DEL in batches; safe to call on a live cache but O(n) in keyspace size. No prefix configured means it's a no-op (we refuse to FLUSHDB a shared Redis).
type RedisOption ¶ added in v0.3.0
RedisOption configures a Redis cache.
func WithCodec ¶ added in v0.3.0
func WithCodec[V any](c Codec[V]) RedisOption[V]
WithCodec swaps the default JSON codec for a custom one (msgpack, protobuf, …).
func WithKeyPrefix ¶ added in v0.3.0
func WithKeyPrefix[V any](prefix string) RedisOption[V]
WithKeyPrefix prepends prefix to every key. The trailing colon is added if missing.
type Tiered ¶ added in v0.3.0
type Tiered[V any] struct { // OnL1Error is called when an L1 operation fails. Defaults to a // no-op; wire to a logger to capture serialization or eviction // errors without aborting the call. OnL1Error func(op string, err error) // L1TTL clamps how long a warmed entry stays in L1. Defaults to // the L2 TTL passed to Set/GetOrLoad. Useful when L1 should // expire faster than L2 to bound staleness. L1TTL time.Duration // contains filtered or unexported fields }
Tiered chains two caches: L1 (fast, local) → L2 (shared, remote). Reads probe L1 first; on miss they probe L2 and warm L1. Writes fan out to both. Failures in L2 surface; failures in L1 are non-fatal and logged via the optional OnL1Error hook.
Typical setup: inmem L1 + redis L2 — sub-µs reads when warm, shared invalidation across pods when cold.