redis

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Sep 8, 2026 License: AGPL-3.0 Imports: 16 Imported by: 0

Documentation

Overview

Package redis implements distributedlock.Locker with a single Redis key per lock.

What it guarantees

Acquire is a SETNX of a prefixed key to a freshly generated ownership token, with the TTL as the key's expiry — so the TTL is enforced by Redis rather than by the holder, and a process that dies mid-hold releases the lock when the key expires rather than when somebody notices.

Release and Refresh are Lua scripts that compare the token before acting, which is what stops one caller releasing or extending a lock that has already expired and been taken by another. Either reports distributedlock.ErrLockNotHeld when the token no longer matches. A held lock whose TTL lapses is indistinguishable, from inside, from one still held: the handle's TTL is what was asked for, not what remains, so work that may outlive its TTL has to Refresh.

What it does not guarantee

Exclusivity rests on that one key, on one Redis. This is not Redlock — nothing here takes a quorum across independent nodes — so the lock is only as durable as the key. Redis replication is asynchronous, so a failover that promotes a replica which has not yet received the SET can hand the same lock to a second caller, and neither caller is told. Where two simultaneous holders would be a correctness failure rather than a wasted duplicate, the lock is not the last line of defense; the work underneath it also needs to be idempotent, or fenced by something the database enforces.

Contention and unavailability are different answers. A key already held reports ErrLockNotAcquired and counts as a healthy round trip — the backend answered. A Redis that cannot be reached trips the circuit breaker, and calls made while it is open report circuitbreaking.ErrCircuitBroken rather than a failure to acquire, so a caller cannot read an outage as contention.

There is no waiting. Acquire either takes the lock or returns immediately; a caller that wants to queue composes retry itself, or uses the parent package's ScopedLocker, which does that polling for it.

Keys are prefixed (default "lock:"), so what is written to Redis is not the key the caller named. Spans carry both.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	Username  string   `env:"USERNAME"   json:"username,omitempty"  yaml:"username,omitempty"`
	Password  string   `env:"PASSWORD"   json:"password,omitempty"  yaml:"password,omitempty"`
	KeyPrefix string   `env:"KEY_PREFIX" envDefault:"lock:"         json:"keyPrefix,omitempty" yaml:"keyPrefix,omitempty"`
	Addresses []string `env:"ADDRESSES"  json:"addresses,omitempty" yaml:"addresses,omitempty"`
}

Config configures a Redis-backed distributed locker.

func (*Config) ValidateWithContext

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

ValidateWithContext validates a Config struct.

type Locker

type Locker struct {
	// contains filtered or unexported fields
}

func NewRedisLocker

func NewRedisLocker(
	cfg *Config,
	cb circuitbreaking.CircuitBreaker,
	opts ...Option,
) (*Locker, error)

NewRedisLocker constructs a new Redis-backed distributedlock.Locker.

func (*Locker) Acquire

func (l *Locker) Acquire(ctx context.Context, key string, ttl time.Duration) (distributedlock.Lock, error)

Acquire implements distributedlock.Locker.

func (*Locker) Close

func (l *Locker) Close() error

Close implements distributedlock.Locker.

func (*Locker) Ping

func (l *Locker) Ping(ctx context.Context) error

Ping implements distributedlock.Locker.

type Option

type Option func(*options)

Option configures the redis-backed Locker this package constructs. The zero configuration works: an absent logger logs nowhere, an absent tracer provider traces nowhere, and an absent metrics provider records nothing.

func WithLogger

func WithLogger(logger logging.Logger) Option

WithLogger attaches a logger.

func WithMetricsProvider

func WithMetricsProvider(metricsProvider metrics.Provider) Option

WithMetricsProvider attaches a metrics provider for the locker's counters and latency histogram.

func WithTracerProvider

func WithTracerProvider(tracerProvider tracing.Provider) Option

WithTracerProvider attaches a tracer provider, enabling spans on every lock operation.

Jump to

Keyboard shortcuts

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