Documentation
¶
Overview ¶
Package cache provides request-hash caching primitives for Parsec. Applications use this to share cached computation results across users and sessions: the cache stores Envelope values (not raw bytes) so a cache hit looks identical to a fresh computation result from the subscriber's point of view.
Two implementations ship:
- MemoryCache (in-process LRU) — fast, no external deps, single-host
- RedisCache (Redis-backed) — shared across processes/machines
Both enforce tenant isolation: tenant-scoped keys are namespaced with a tenant prefix so cross-tenant cache leakage is impossible by construction.
Index ¶
- Variables
- func Backend(c Cache) string
- type BackendReporter
- type Cache
- type MemoryCache
- func (c *MemoryCache) Close()
- func (c *MemoryCache) Delete(_ context.Context, key string) error
- func (c *MemoryCache) DeleteForTenant(ctx context.Context, tenantID, key string) error
- func (c *MemoryCache) Get(_ context.Context, key string) (envelope.Envelope, bool, error)
- func (c *MemoryCache) GetForTenant(ctx context.Context, tenantID, key string) (envelope.Envelope, bool, error)
- func (c *MemoryCache) Put(_ context.Context, key string, env envelope.Envelope, ttl time.Duration) error
- func (c *MemoryCache) PutForTenant(ctx context.Context, tenantID, key string, env envelope.Envelope, ...) error
- func (c *MemoryCache) Stats() Stats
- type NoopCache
- func (NoopCache) Delete(context.Context, string) error
- func (NoopCache) DeleteForTenant(context.Context, string, string) error
- func (NoopCache) Get(context.Context, string) (envelope.Envelope, bool, error)
- func (NoopCache) GetForTenant(context.Context, string, string) (envelope.Envelope, bool, error)
- func (NoopCache) Put(context.Context, string, envelope.Envelope, time.Duration) error
- func (NoopCache) PutForTenant(context.Context, string, string, envelope.Envelope, time.Duration) error
- func (NoopCache) Stats() Stats
- type RedisCache
- func (c *RedisCache) Delete(ctx context.Context, key string) error
- func (c *RedisCache) DeleteForTenant(ctx context.Context, tenantID, key string) error
- func (c *RedisCache) Get(ctx context.Context, key string) (envelope.Envelope, bool, error)
- func (c *RedisCache) GetForTenant(ctx context.Context, tenantID, key string) (envelope.Envelope, bool, error)
- func (c *RedisCache) Put(ctx context.Context, key string, env envelope.Envelope, ttl time.Duration) error
- func (c *RedisCache) PutForTenant(ctx context.Context, tenantID, key string, env envelope.Envelope, ...) error
- func (c *RedisCache) Stats() Stats
- type Stats
Constants ¶
This section is empty.
Variables ¶
var ErrCacheMiss = errors.New("cache: miss")
ErrCacheMiss is the sentinel returned by Get / GetForTenant when the key is absent. Callers should errors.Is against this rather than relying on the (_, false) return convention; the bool is the primary signal but the error variant is here for chained APIs.
Functions ¶
func Backend ¶ added in v0.3.0
Backend reports the implementation name. The manifest surfaces this so SDKs and dashboards can distinguish memory / redis / noop without reflecting on the cache value. A BackendReporter implementation (typically a metrics wrapper) is asked first so wrappers are transparent.
Types ¶
type BackendReporter ¶ added in v0.3.0
type BackendReporter interface {
Backend() string
}
BackendReporter is an optional escape hatch for caches wrapped in a transparent observer (metrics, tracing). The wrapper implements this to expose the underlying backend without exposing the inner Cache itself.
type Cache ¶
type Cache interface {
Get(ctx context.Context, key string) (envelope.Envelope, bool, error)
Put(ctx context.Context, key string, env envelope.Envelope, ttl time.Duration) error
Delete(ctx context.Context, key string) error
GetForTenant(ctx context.Context, tenantID, key string) (envelope.Envelope, bool, error)
PutForTenant(ctx context.Context, tenantID, key string, env envelope.Envelope, ttl time.Duration) error
DeleteForTenant(ctx context.Context, tenantID, key string) error
// Stats returns a snapshot of cache counters. The shape is shared
// across implementations so the telemetry surface can render the
// same JSON for either backend.
Stats() Stats
}
Cache is the surface Parsec applications consume. Implementations are safe for concurrent use.
Tenant-scoped variants exist because most Parsec deployments are multi-tenant; using GetForTenant / PutForTenant makes cross-tenant leakage a compile-time impossibility for callers that consistently use the tenant-scoped API.
type MemoryCache ¶
type MemoryCache struct {
MaxEntries int
SweepInterval time.Duration
// contains filtered or unexported fields
}
MemoryCache is an LRU cache with per-entry TTL. The LRU is bounded by MaxEntries; when full, the least-recently-used entry is evicted.
Expired entries are evicted lazily on Get and proactively by a background goroutine that ticks every SweepInterval.
func NewMemoryCache ¶
func NewMemoryCache(maxEntries int) *MemoryCache
NewMemoryCache constructs a cache holding at most maxEntries items. maxEntries <= 0 falls back to 4096.
func (*MemoryCache) Close ¶
func (c *MemoryCache) Close()
Close stops the background sweeper. Safe to call multiple times.
func (*MemoryCache) Delete ¶
func (c *MemoryCache) Delete(_ context.Context, key string) error
Delete removes key. No-op if absent.
func (*MemoryCache) DeleteForTenant ¶
func (c *MemoryCache) DeleteForTenant(ctx context.Context, tenantID, key string) error
DeleteForTenant is Delete with a tenant-scoped key.
func (*MemoryCache) GetForTenant ¶
func (c *MemoryCache) GetForTenant(ctx context.Context, tenantID, key string) (envelope.Envelope, bool, error)
GetForTenant is Get with a tenant-scoped key.
func (*MemoryCache) Put ¶
func (c *MemoryCache) Put(_ context.Context, key string, env envelope.Envelope, ttl time.Duration) error
Put inserts env under key with ttl (zero ttl = no expiry).
func (*MemoryCache) PutForTenant ¶
func (c *MemoryCache) PutForTenant(ctx context.Context, tenantID, key string, env envelope.Envelope, ttl time.Duration) error
PutForTenant is Put with a tenant-scoped key.
func (*MemoryCache) Stats ¶
func (c *MemoryCache) Stats() Stats
Stats returns a snapshot of the cache counters.
type NoopCache ¶ added in v0.3.0
type NoopCache struct{}
NoopCache is the "cache disabled" sentinel. Get always misses; Put, Delete, and their tenant-scoped twins are no-ops. Useful as an explicit opt-out when parsec.Options.RedisClient is set but the embedder does NOT want the auto-built Redis cache.
func NewNoopCache ¶ added in v0.3.0
func NewNoopCache() NoopCache
NewNoopCache returns the singleton NoopCache value.
func (NoopCache) DeleteForTenant ¶ added in v0.3.0
func (NoopCache) GetForTenant ¶ added in v0.3.0
func (NoopCache) PutForTenant ¶ added in v0.3.0
type RedisCache ¶
type RedisCache struct {
Client redis.UniversalClient
KeyPrefix string
// contains filtered or unexported fields
}
RedisCache is the cross-host implementation. Envelopes are stored as JSON; keys are prefixed with KeyPrefix.
Stats are best-effort (Hits/Misses/Puts are local counters for this process; Evictions and SizeEntries are not tracked — Redis handles expiry and total size via its own metrics).
func NewRedisCache ¶
func NewRedisCache(c redis.UniversalClient, prefix string) *RedisCache
NewRedisCache constructs a Redis-backed cache. prefix is namespaced (default "parsec:cache").
func (*RedisCache) Delete ¶
func (c *RedisCache) Delete(ctx context.Context, key string) error
Delete removes key.
func (*RedisCache) DeleteForTenant ¶
func (c *RedisCache) DeleteForTenant(ctx context.Context, tenantID, key string) error
func (*RedisCache) GetForTenant ¶
func (c *RedisCache) GetForTenant(ctx context.Context, tenantID, key string) (envelope.Envelope, bool, error)
GetForTenant / PutForTenant / DeleteForTenant — tenant-scoped variants.
func (*RedisCache) Put ¶
func (c *RedisCache) Put(ctx context.Context, key string, env envelope.Envelope, ttl time.Duration) error
Put serializes env and writes it under key with ttl.
func (*RedisCache) PutForTenant ¶
func (*RedisCache) Stats ¶
func (c *RedisCache) Stats() Stats
Stats returns a snapshot of local counters.
type Stats ¶
type Stats struct {
Hits int64 `json:"hits"`
Misses int64 `json:"misses"`
Puts int64 `json:"puts"`
Evictions int64 `json:"evictions"`
// SizeEntries is the count of entries currently held. For
// distributed caches (Redis) this value is approximate — the
// implementation may report 0 to avoid a costly DBSIZE call.
SizeEntries int64 `json:"size_entries"`
}
Stats is the cross-implementation counter snapshot.