cachecfg

package
v11.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2026 License: AGPL-3.0 Imports: 14 Imported by: 0

Documentation

Overview

Package cachecfg selects and builds a cache.Cache[T] from configuration: either the in-process memory cache or Redis.

There is deliberately no default provider. Whether a cache lives in this process or in Redis is a fact about a deployment rather than something a library can pick, so an unset Provider fails validation instead of quietly becoming a memory cache. Several fields — MaxEntries, EvictionPolicy, JanitorInterval — are read only by the memory provider, which is the only one holding entries in this process's heap.

Index

Constants

View Source
const (
	// ProviderMemory is the memory provider.
	ProviderMemory = "memory"
	// ProviderRedis is the redis provider.
	ProviderRedis = "redis"
)

Variables

This section is empty.

Functions

func NewCache

func NewCache[T any](ctx context.Context, cfg *Config, opts ...Option) (cache.Cache[T], error)

NewCache provides a Cache.

Each provider is built into a variable and returned only once its error is known to be nil, rather than returned straight from the constructor. The provider constructors return their own concrete types, so `return memory.NewInMemoryCache[T](...)` would convert a nil *memory.Cache[T] into a non-nil cache.Cache[T] on the error path, and a caller testing the returned interface against nil would find a cache that panics on first use.

Types

type Config

type Config struct {
	Redis    *redis.Config `env:",init"    envPrefix:"REDIS_"        json:"redis,omitempty"    yaml:"redis,omitempty"`
	Provider string        `env:"PROVIDER" json:"provider,omitempty" yaml:"provider,omitempty"`
	// EvictionPolicy names which entry the memory provider drops once
	// MaxEntries is reached: "least_recently_used" (alias "lru") or
	// "oldest_written" (alias "fifo"). It is read only when MaxEntries is
	// positive, so the default here costs an unbounded cache nothing.
	EvictionPolicy string                    `env:"EVICTION_POLICY" envDefault:"least_recently_used" json:"evictionPolicy,omitempty"      yaml:"evictionPolicy,omitempty"`
	CircuitBreaker circuitbreakingcfg.Config `` /* 129-byte string literal not displayed */
	// Expiry is the default expiry for writes that don't specify one via
	// cache.WithExpiry; a non-positive value means entries never expire by
	// default.
	Expiry time.Duration `env:"EXPIRY" envDefault:"1h" json:"expiry,omitempty" yaml:"expiry,omitempty"`
	// JanitorInterval is how often the memory provider sweeps expired
	// entries. It is ignored by every other provider, which expire entries
	// in the backing store rather than in this process. A non-positive
	// value disables the sweep, leaving the memory provider's lazy
	// eviction as the only reclaim path — see memory.WithJanitor for why
	// that is rarely what a long-lived cache wants.
	JanitorInterval time.Duration `env:"JANITOR_INTERVAL" envDefault:"5m" json:"janitorInterval,omitempty" yaml:"janitorInterval,omitempty"`
	// MaxEntries bounds how many entries the memory provider holds,
	// dropping one per EvictionPolicy whenever a write would exceed it. It
	// is ignored by every other provider, which bound their own storage.
	// A non-positive value leaves the cache bounded only by expiry — see
	// memory.WithMaxEntries for when that is not enough.
	MaxEntries int `env:"MAX_ENTRIES" json:"maxEntries,omitempty" yaml:"maxEntries,omitempty"`
}

Config is the configuration for the cache.

func (*Config) ValidateWithContext

func (cfg *Config) ValidateWithContext(ctx context.Context) error

ValidateWithContext validates a Config struct.

The sub-config for a provider that was not selected is skipped rather than merely unguarded: ozzo validates any non-nil pointer to a Validatable once a field's rules have run, and `env:",init"` leaves every sub-config non-nil. A validation.When guard alone stops the Required rule and nothing else, so Redis' own rules were enforced and the memory provider could not load.

type Option

type Option func(*options)

Option configures how NewCache assembles its cache.

The observability dependencies are options rather than parameters because every one of them is genuinely optional: an absent logger logs nowhere, an absent tracer provider traces nowhere, and an absent metrics provider records nothing. Requiring them positionally made a caller that wanted none of the three name all three anyway, usually as noops.

It carries no type parameter even though NewCache does. Go cannot infer a type argument from a call's result type, so an Option[T] would force every call site to spell the cached type out by hand — WithLogger[MyValue](l) — forever.

func WithLogger

func WithLogger(logger logging.Logger) Option

WithLogger attaches a logger. An absent logger logs nowhere.

func WithMetricsProvider

func WithMetricsProvider(metricsProvider metrics.Provider) Option

WithMetricsProvider attaches a metrics provider for the cache's counters and latency histogram. An absent provider records nothing.

func WithPillars

func WithPillars(p *observability.Pillars) Option

WithPillars attaches a logger, tracer provider, and metrics provider in one go, for the common case where a caller has already built them together. A nil Pillars attaches nothing.

It is applied in order with the individual options, so a caller can hand over its pillars and then override one of them:

cachecfg.NewCache[Session](ctx, cfg,
	cachecfg.WithPillars(pillars),
	cachecfg.WithMetricsProvider(nil), // this cache stays unmetered
)

func WithTracerProvider

func WithTracerProvider(tracerProvider tracing.Provider) Option

WithTracerProvider attaches a tracer provider, enabling spans on every cache operation. An absent tracer provider traces nowhere.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL