Documentation
¶
Overview ¶
Package cache provides a Redis + in-memory hybrid cache for nexus apps, ported from the oats_applicant implementation. A Manager always has the in-memory store ready; in "production" mode it also tries to keep a Redis connection, falling back to memory on outage and reconnecting on a 30s tick.
Typical wiring with fx:
fx.New(
fx.Provide(zap.NewExample),
cache.Module, // provides *cache.Manager + *cache.Config
fx.Invoke(func(app *nexus.App, m *cache.Manager) {
app.Register(m.AsResource("session-cache", "Hybrid redis/memory"))
}),
)
Without fx, call NewConfig() + NewManager(cfg, logger) and Start().
Index ¶
- Variables
- func ManifestEnv() []manifest.EnvVar
- func ManifestService() manifest.ServiceNeed
- type Config
- type Manager
- func (m *Manager) AsResource(name, description string, opts ...resource.Option) resource.Resource
- func (m *Manager) Clear(ctx context.Context) error
- func (m *Manager) Delete(ctx context.Context, key string) error
- func (m *Manager) Get(ctx context.Context, key string, out any) error
- func (m *Manager) IsRedisConnected() bool
- func (m *Manager) NexusEnv() []manifest.EnvVar
- func (m *Manager) NexusServices() []manifest.ServiceNeed
- func (m *Manager) Set(ctx context.Context, key string, value any, ttl time.Duration) error
- func (m *Manager) Start()
- func (m *Manager) Stop()
Constants ¶
This section is empty.
Variables ¶
Module provides *Config (from env) and *Manager into the Fx graph. Consume it by taking *cache.Manager in your constructors.
Functions ¶
func ManifestEnv ¶ added in v0.22.1
ManifestEnv lists the env vars this package's NewConfig reads. Apps that include cache.Module in their nexus.Run options should also add nexus.DeclareEnvList(cache.ManifestEnv()) so the deploy-time manifest reflects the cache's configuration surface — otherwise an orchestration platform reading the manifest won't know REDIS_HOST / REDIS_PORT / REDIS_PASSWORD / APP_ENV are required.
Two design notes:
We expose a slice rather than implementing manifest.EnvProvider on *Manager. EnvProvider would only be detected once *Manager enters the graph, but in print mode we want declarations visible WITHOUT firing constructors (Manager's constructor dials Redis). Static slices are side-effect-free by definition.
We expose ManifestService too — the cache's logical sidecar ("redis"). Both are returned together as a convenience but kept as separate functions so an app that, say, uses an external managed Redis (no provisioned sidecar needed) can include ManifestEnv() but skip ManifestService().
func ManifestService ¶ added in v0.22.1
func ManifestService() manifest.ServiceNeed
ManifestService describes the Redis sidecar this package would like the orchestration platform to provision. Optional=true reflects that the cache layer degrades to in-memory when Redis is absent — the platform can skip provisioning in dev environments where that trade-off is acceptable.
Types ¶
type Config ¶
type Config struct {
// Environment controls Redis behavior. "production" attempts Redis and
// keeps reconnecting; anything else stays on memory.
Environment string
RedisHost string
RedisPort string
RedisPassword string
RedisDB int
// DefaultExpiry is go-cache's default TTL. CleanupExpiry is its GC tick.
DefaultExpiry time.Duration
CleanupExpiry time.Duration
// ConnectTimeout caps the initial Redis ping during connect attempts.
ConnectTimeout time.Duration
// ReconnectInterval controls how often the manager retries Redis when
// it's down. 0 defaults to 30s.
ReconnectInterval time.Duration
}
Config holds cache configuration. Populate via NewConfig (env-driven) or construct directly.
func NewConfig ¶
func NewConfig() *Config
NewConfig builds a Config from env vars: APP_ENV, REDIS_HOST, REDIS_PORT, REDIS_PASSWORD. Defaults: env=development, host=localhost, port=6379, db=0, 15m/10m expiries, 5s connect timeout, 30s reconnect.
func (*Config) RedisAddress ¶
RedisAddress returns host:port, filling in localhost:6379 when blank.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager is the live cache. Its Get/Set/Delete are safe for concurrent use; the underlying store flips between Redis and memory atomically under a mutex when connectivity changes.
func NewManager ¶
NewManager constructs a Manager with the in-memory store initialized. Redis connection, when enabled via "production" mode, is attempted asynchronously in Start() so an unreachable Redis never delays boot. Call Start() to kick off the connect + reconnect loop.
func Provide ¶
Provide is the fx provider: builds a Manager from a *Config, ties its Start/Stop to the Fx lifecycle, AND self-registers as a manifest.EnvProvider + ServiceDependencyProvider so the orchestration manifest reflects this cache's REDIS_HOST/PORT/ PASSWORD requirements without the app's main.go having to call nexus.DeclareEnv / DeclareService.
reg comes from the fx graph — *nexus.App satisfies the interface (it has matching methods) and is provided by fxEarlyOptions, so every app that uses cache.Module gets the registration for free. Apps that build their own *App via nexus.New() still wire it the same way.
func (*Manager) AsResource ¶
AsResource builds a nexus resource.Resource for this Manager. Mark it as default with extra options passed through. Backend ("redis" vs "memory") is reported live via WithDetails.
func (*Manager) Get ¶
Get deserializes the cached value under key into out. Returns an error if the key is missing or the cache isn't initialized.
func (*Manager) IsRedisConnected ¶
IsRedisConnected reports whether Redis is the currently active store.
func (*Manager) NexusEnv ¶ added in v0.22.2
── Auto-discovered manifest providers ─────────────────────────────
*Manager implements manifest.EnvProvider and manifest.ServiceDependencyProvider so nexus.Provide auto-walks the constructed Manager at print-mode boot and pulls these declarations into the manifest. No nexus.DeclareEnv / DeclareService calls in the application's main.go — adoption is just `cache.Module`.
Methods are static (no read of m.config) so print mode gets the same answer pre-Start as a fully-running Manager — preserves the side-effect-free contract.
func (*Manager) NexusServices ¶ added in v0.22.2
func (m *Manager) NexusServices() []manifest.ServiceNeed
func (*Manager) Start ¶
func (m *Manager) Start()
Start kicks off the background reconnect/health loop and fires the first Redis connect attempt asynchronously. Safe to call once; the whole path is skipped outside production mode. Callers never block on Redis availability — the manager serves from memory until Redis comes up, then flips atomically under the mutex.