Documentation
¶
Overview ¶
Package lock builds a config-selected core/interfaces.Locker — a DistributedLock (keyed, token-fenced, best-effort) plus Hold, the managed acquire-with-watchdog helper a single-active-operation guard depends on.
NewFromConfig chooses a backend from a Kind string — local (in-process, dev / replica=1) or redis (cross-pod, staging/prod) — mirroring the foundation/logger.NewFromConfig and clients/cache factory pattern, and wraps it in a Locker (NewLocker). The redis backend reuses the live go-redis client from the cache (clients/cache/redis.Cache.Client), so no second connection pool is opened.
Hold acquires a key and keeps its lease alive with a background watchdog; the context it returns is cancelled the instant the lease is lost, so a losing pod's in-flight work is stopped rather than left running under a lock it no longer owns. Key naming is the caller's.
Cross-cutting concerns are composed by the decorators subpackage (resilience: retry, circuit-breaker, timeout; observability: logging, metrics, tracing), wired by NewFromConfig from the Config collaborators.
Scope boundary: this package ships both backends, the factory, the decorator stack, and Hold. Wiring them (config + shared redis client + observability/resilience deps → Locker) and choosing the call sites and key names belong to the consumer's composition root.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewFromConfig ¶
NewFromConfig builds the configured Locker: it selects a DistributedLock backend by Kind, wraps it in the resilience + observability decorator stack (from the Config collaborators — each optional/nil-safe), and returns a Locker whose Hold renews on RenewInterval over the decorated backend. The client is required only for KindRedis (the shared go-redis client reused from the cache); it is ignored for KindLocal. It fails loudly on an unknown kind, a non-positive TTL or RenewInterval, a RenewInterval that exceeds TTL/3, or a redis kind with no client.
func NewLocker ¶
func NewLocker( lock interfaces.DistributedLock, renewInterval time.Duration, ) interfaces.Locker
NewLocker wraps a DistributedLock with the renewal cadence Hold uses, yielding a Locker. Exposed so callers (and tests) can compose Hold over any DistributedLock — e.g. a mock or a backend built directly; NewFromConfig builds one over the config-selected backend.
Types ¶
type Config ¶
type Config struct {
// Logger drives the logging decorator; nil skips it.
Logger interfaces.Logger
// Metrics drives the metrics decorator; nil skips it.
Metrics interfaces.Metrics
// Tracer drives the tracing decorator; nil skips it.
Tracer interfaces.Tracer
// Retrier drives the retry decorator (transient-error retries); nil skips it.
Retrier interfaces.Retrier
// CircuitBreaker drives the circuit-breaker decorator; nil skips it.
CircuitBreaker interfaces.CircuitBreaker
// Name labels the lock in metrics, spans, and logs (default "lock").
Name string
// Kind selects the backend (local | redis).
Kind Kind
// TTL is the lease duration applied on Acquire and extended by Renew.
TTL time.Duration
// RenewInterval is the watchdog's renew cadence in Hold.
RenewInterval time.Duration
// OpTimeout bounds each backend operation via the timeout decorator; zero
// skips it.
OpTimeout time.Duration
}
Config selects and tunes the lock. Kind picks the backend; TTL is the lease duration a holder gets on Acquire (and Renew extends); RenewInterval is how often Hold's watchdog renews. RenewInterval must be ≤ TTL/3 so a couple of missed renew ticks cannot expire a live lease.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package decorators composes cross-cutting concerns — resilience (retry, circuit-breaker, timeout) and observability (logging, metrics, tracing) — around any core/interfaces.DistributedLock, without touching the backend.
|
Package decorators composes cross-cutting concerns — resilience (retry, circuit-breaker, timeout) and observability (logging, metrics, tracing) — around any core/interfaces.DistributedLock, without touching the backend. |
|
Package local provides an in-process DistributedLock backend for single-pod deployments (dev / replica=1), where cross-process coordination is unnecessary.
|
Package local provides an in-process DistributedLock backend for single-pod deployments (dev / replica=1), where cross-process coordination is unnecessary. |
|
Package redis provides a cross-pod DistributedLock backend over Redis, for multi-replica deployments (staging/prod).
|
Package redis provides a cross-pod DistributedLock backend over Redis, for multi-replica deployments (staging/prod). |