Documentation
¶
Overview ¶
Package distlock provides distributed, automatically renewed leases across independent nodes.
Its quorum and lease semantics are based on the Redlock algorithm described at https://redis.io/docs/latest/develop/clients/patterns/distributed-locks/. The core package is independent of storage and network transport and does not require Redis. Applications that communicate with remote nodes over gRPC can use the grpc subpackage to expose and call node-local lease operations.
A Cluster must return every node in the lock group, including temporarily unavailable nodes, because every node counts toward quorum. Changing the node set is unsafe if a new quorum can be disjoint from an earlier quorum while leases acquired from the earlier node set may still be valid. Callers must stop protected work when the context returned by Lease.Context is done.
Index ¶
- Constants
- Variables
- type Cluster
- type Config
- type Lease
- type Locker
- type MemoryStore
- func (s *MemoryStore) Acquire(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
- func (s *MemoryStore) Release(ctx context.Context, resource string, token []byte) (bool, error)
- func (s *MemoryStore) Renew(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
- type Node
- type Store
Constants ¶
const ( DefaultLeaseDuration = 10 * time.Second DefaultClockDriftFactor = 0.01 DefaultMaxNodeCallTimeout = 5 * time.Second )
Variables ¶
var ( // ErrLeaseLost is the cancellation cause when automatic renewal can no longer maintain a lease. ErrLeaseLost = errors.New("distributed lease lost") // ErrLeaseReleased is the cancellation cause of an explicitly released lease. ErrLeaseReleased = errors.New("distributed lease released") )
Functions ¶
This section is empty.
Types ¶
type Cluster ¶
type Cluster interface {
// Nodes returns each node counted toward quorum exactly once, including nodes that are temporarily unavailable.
// The Locker may keep and use the returned nodes throughout acquisition and until any acquired lease is released.
Nodes(ctx context.Context) ([]Node, error)
}
Cluster provides point-in-time snapshots of the independent nodes that participate in distributed leases. Implementations must be safe for concurrent use.
type Config ¶
type Config struct {
// LeaseDuration is the TTL used for acquisitions and renewals. The default is DefaultLeaseDuration.
LeaseDuration time.Duration
// ClockDriftFactor is the fraction of LeaseDuration reserved for differences in clock rates between the Locker and
// nodes. The default is DefaultClockDriftFactor.
ClockDriftFactor float64
// NodeCallTimeout sets the context timeout for an Acquire, Renew, or Release call to one node.
// The default is the smaller of DefaultMaxNodeCallTimeout and one third of the lease duration.
NodeCallTimeout time.Duration
// NewBackOff creates independent retry policies for acquisitions and renewal cycles. The default is an exponential
// backoff starting at 100ms and capped at 1s. A policy should not impose its own elapsed-time limit because the
// acquisition context and current lease validity already bound retries.
NewBackOff func() backoff.BackOff
}
Config configures a Locker.
type Lease ¶
type Lease struct {
// contains filtered or unexported fields
}
Lease is an automatically renewed distributed lease.
type Locker ¶
type Locker struct {
// contains filtered or unexported fields
}
Locker acquires automatically renewed distributed leases over a Cluster.
type MemoryStore ¶
type MemoryStore struct {
// contains filtered or unexported fields
}
MemoryStore stores leases in memory. Its contents are lost when the process exits.
func NewMemoryStore ¶
func NewMemoryStore() *MemoryStore
NewMemoryStore creates an empty in-memory lease store.
func (*MemoryStore) Acquire ¶
func (s *MemoryStore) Acquire( ctx context.Context, resource string, token []byte, ttl time.Duration, ) (bool, error)
Acquire creates a lease when the resource does not have an unexpired lease.
type Node ¶
type Node interface {
// Acquire creates a lease when resource does not have an unexpired lease.
Acquire(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
// Renew extends an unexpired lease when its ownership token matches.
Renew(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
// Release removes an unexpired lease when its ownership token matches.
Release(ctx context.Context, resource string, token []byte) (bool, error)
}
Node provides lease operations on a single cluster node.
Each operation performs one attempt. A true result means the operation took effect. A false result with no error means the node responded but its lease state rejected the operation. If err is non-nil, the result is unknown and the boolean result must be ignored. Implementations must return promptly when ctx is cancelled, not modify token, and be safe for concurrent use.
type Store ¶
type Store interface {
// Acquire creates a lease when the resource does not have an unexpired lease.
Acquire(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
// Renew extends an unexpired lease when its ownership token matches.
Renew(ctx context.Context, resource string, token []byte, ttl time.Duration) (bool, error)
// Release removes a lease when its ownership token matches.
Release(ctx context.Context, resource string, token []byte) (bool, error)
}
Store holds node-local lease state and provides atomic operations over it.