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
- 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 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 ¶
This section is empty.
Types ¶
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 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.