-
Release v1.0.0 Stable
released this
2026-05-29 09:59:33 -06:00 | 0 commits to main since this releasev1.0.0
code.nochebuena.dev/einherjar/cache-valkey
Architecture Decisions Resolved
Decision Outcome Flat package No sub-packages — all adapters wrap the same Provider; no sub-concern is independently usable without the connection (see ADR-001) Provider interface Six common ops + Native() vk.Clientescape hatch — follows micro-lib minio pattern (see ADR-002)Adapter constructors Take Provider, notvk.Client— adapters testable with mockProvider, no live server required (see ADR-003)IncrWithTTL implementation Lua script — atomic INCR + conditional EXPIRE; race-free fixed-window counter (see ADR-004) Health priority LevelDegraded— Valkey outage degrades, does not halt the service (see ADR-005)
API
import cachevalkey "code.nochebuena.dev/einherjar/cache-valkey" // Interfaces type Provider interface { Get(ctx context.Context, key string) (string, bool, error) Set(ctx context.Context, key string, value string, ttl time.Duration) error Del(ctx context.Context, keys ...string) error Exists(ctx context.Context, key string) (bool, error) Expire(ctx context.Context, key string, ttl time.Duration) error IncrWithTTL(ctx context.Context, key string, ttl time.Duration) (int64, error) Native() vk.Client } type Component interface { lifecycle.Component observability.Checkable observability.Identifiable Provider } // Config (caarlos0/env compatible) type Config struct { Addrs []string // EINHERJAR_VALKEY_ADDRS,required Password string // EINHERJAR_VALKEY_PASSWORD SelectDB int // EINHERJAR_VALKEY_DB (default: 0) CacheSizeEachConn int // EINHERJAR_VALKEY_CLIENT_CACHE_MB (default: 0) } // Constructor func New(logger logging.Logger, cfg Config) Component // Adapters (duck-typed — no cross-module import required) func NewPermissionCache(p Provider) *PermissionCache // → auth/rbac.Cache func NewRateLimiterStore(p Provider, window time.Duration, limit int64) *RateLimiterStore // → web/mw.RateLimiterStore func NewBlacklist(p Provider) *Blacklist // → auth-jwt.Blacklist
Wiring example
vk := cachevalkey.New(logger, cfg) launcher.Register(vk) health.Register(vk) // Create adapters — each satisfies one interface in another module. // Go's structural typing handles the assignment; no cast required. permCache := cachevalkey.NewPermissionCache(vk) rateLimiter := cachevalkey.NewRateLimiterStore(vk, time.Second, 100) blacklist := cachevalkey.NewBlacklist(vk) // Wire into consuming modules directly: permProvider := rbac.NewCachedPermissionProvider(permCache, baseProvider, rbac.CacheConfig{TTL: 5 * time.Minute}) router.Use(mw.IPRateLimit(rateLimiter)) pair, err := authjwt.RefreshTokenPair(ctx, signer, oldRefreshToken, blacklist, tokenCfg, newClaims)
Install
go get code.nochebuena.dev/einherjar/cache-valkey@v1.0.0
Dependencies
Module Version Role code.nochebuena.dev/einherjar/contractsv1.0.0 lifecycle.Component,observability.Checkable,logging.Loggercode.nochebuena.dev/einherjar/corev1.0.0 xerrorsgithub.com/valkey-io/valkey-gov1.0.54 Native Valkey client Downloads