Documentation
¶
Overview ¶
Package lock provides distributed locking utilities for all services.
This package implements distributed locking using Redis with proper error handling, automatic retry, and lock expiration.
Example:
lock := lock.NewRedisLock(redisClient)
err := lock.Execute(ctx, "my-resource", 30*time.Second, func() error {
// Critical section - only one instance will execute this
return doWork()
})
Metrics support:
lock := lock.NewRedisLock(redisClient, lock.WithMetrics(lock.MetricsConfig{
EnableWaitTime: true,
EnableContention: true,
}))
Metrics exported:
- mesh_lock_acquired_total{key,owner} - locks acquired
- mesh_lock_wait_seconds{key,owner} - wait time to acquire
- mesh_lock_contention_total{key,owner} - contention events
Index ¶
- Variables
- type LockResult
- type MemoryLock
- type MetricsConfig
- type Option
- type RedisClient
- type RedisLock
- func (r *RedisLock) Acquire(ctx context.Context, key string, ttl time.Duration, maxWait time.Duration) (*LockResult, error)
- func (r *RedisLock) Execute(ctx context.Context, key string, ttl time.Duration, fn func() error) error
- func (r *RedisLock) ExecuteWithRetry(ctx context.Context, key string, ttl time.Duration, maxRetries int, ...) error
- func (r *RedisLock) ExtendLock(ctx context.Context, key, lockID string, ttl, interval time.Duration) error
- func (r *RedisLock) GetLockID(ctx context.Context, key string) (string, error)
- func (r *RedisLock) IsLocked(ctx context.Context, key string) (bool, error)
- func (r *RedisLock) Refresh(ctx context.Context, key, lockID string, ttl time.Duration) error
- func (r *RedisLock) Release(ctx context.Context, key string) error
- func (r *RedisLock) ReleaseWithID(ctx context.Context, key, lockID string) error
- func (r *RedisLock) TryAcquire(ctx context.Context, key string, ttl time.Duration) (*LockResult, error)
Constants ¶
This section is empty.
Variables ¶
var ( // ErrLockFailed is returned when lock cannot be acquired ErrLockFailed = errors.New("failed to acquire lock") // ErrLockNotHeld is returned when trying to release a lock not held ErrLockNotHeld = errors.New("lock not held") // ErrLockExpired is returned when a lock has expired ErrLockExpired = errors.New("lock has expired") // ErrInvalidLockDuration is returned for invalid lock durations ErrInvalidLockDuration = errors.New("lock duration must be positive") )
Functions ¶
This section is empty.
Types ¶
type LockResult ¶
type LockResult struct {
Acquired bool // Whether the lock was acquired
LockID string // Unique identifier for this lock instance
WaitTime time.Duration // Time waited to acquire the lock
ExpiresAt time.Time // When the lock will expire
}
LockResult contains information about a lock operation
type MemoryLock ¶
type MemoryLock struct {
// contains filtered or unexported fields
}
MemoryLock is an in-memory implementation for testing or single-instance deployments
func NewMemoryLock ¶
func NewMemoryLock() *MemoryLock
NewMemoryLock creates a new in-memory lock manager
func (*MemoryLock) Execute ¶
func (m *MemoryLock) Execute(ctx context.Context, key string, ttl time.Duration, fn func() error) error
Execute runs a function while holding an in-memory lock
func (*MemoryLock) Release ¶
func (m *MemoryLock) Release(ctx context.Context, key string) error
Release releases an in-memory lock
func (*MemoryLock) TryAcquire ¶
func (m *MemoryLock) TryAcquire(ctx context.Context, key string, ttl time.Duration) (*LockResult, error)
TryAcquire attempts to acquire an in-memory lock
type MetricsConfig ¶ added in v0.1.16
type MetricsConfig struct {
// EnableWaitTime tracks time waited to acquire locks
EnableWaitTime bool
// EnableContention tracks contention events
EnableContention bool
}
MetricsConfig holds configuration for lock metrics.
type Option ¶ added in v0.1.16
type Option func(*RedisLock)
Option configures RedisLock
func WithMetrics ¶ added in v0.1.16
func WithMetrics(cfg MetricsConfig) Option
WithMetrics enables metrics collection
type RedisClient ¶
type RedisClient interface {
SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) *redis.BoolCmd
Del(ctx context.Context, keys ...string) *redis.IntCmd
Eval(ctx context.Context, script string, keys []string, args ...interface{}) *redis.Cmd
}
RedisClient interface defines the required Redis methods for locking
type RedisLock ¶
type RedisLock struct {
// contains filtered or unexported fields
}
RedisLock implements distributed locking using Redis
func NewRedisLock ¶
func NewRedisLock(client RedisClient, opts ...Option) *RedisLock
NewRedisLock creates a new Redis-based lock manager
func (*RedisLock) Acquire ¶
func (r *RedisLock) Acquire(ctx context.Context, key string, ttl time.Duration, maxWait time.Duration) (*LockResult, error)
Acquire acquires a lock with automatic retry
func (*RedisLock) Execute ¶
func (r *RedisLock) Execute(ctx context.Context, key string, ttl time.Duration, fn func() error) error
Execute runs a function while holding a lock
func (*RedisLock) ExecuteWithRetry ¶
func (r *RedisLock) ExecuteWithRetry(ctx context.Context, key string, ttl time.Duration, maxRetries int, fn func() error) error
ExecuteWithRetry runs a function while holding a lock, with retry if the function fails
func (*RedisLock) ExtendLock ¶
func (r *RedisLock) ExtendLock(ctx context.Context, key, lockID string, ttl, interval time.Duration) error
ExtendLock automatically extends a lock at regular intervals
func (*RedisLock) ReleaseWithID ¶
ReleaseWithID releases a lock only if it matches the given lock ID
func (*RedisLock) TryAcquire ¶
func (r *RedisLock) TryAcquire(ctx context.Context, key string, ttl time.Duration) (*LockResult, error)
TryAcquire attempts to acquire a lock without retry