Documentation
¶
Overview ¶
Package resourcelock provides distributed locking for Kubernetes resources using coordination.k8s.io/v1 Lease objects.
Locks are short-lived (held for milliseconds during a single write) and are not renewed in the background. This makes the implementation simpler than a full leader-election library while still being safe for serializing concurrent access to a shared resource (e.g. a ConfigMap) across replicas.
Usage:
rl := resourcelock.NewResourceLocker(client, "my-namespace")
if err := rl.AcquireLock(ctx, "my-lock", "holder-abc"); err != nil { ... }
defer rl.ReleaseLock(ctx, "my-lock", "holder-abc")
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrLockHeld = errors.New("resourcelock: lock is held by another locker")
ErrLockHeld is returned when a lock cannot be acquired within the retry timeout because another locker holds it.
Functions ¶
This section is empty.
Types ¶
type Option ¶
type Option func(*ResourceLocker)
Option configures a ResourceLocker.
func WithLeaseDuration ¶
WithLeaseDuration sets the lease duration. Default is 15 seconds. Sub-second values are rounded up to 1 second; non-positive values are ignored.
func WithRetryInterval ¶
WithRetryInterval sets the interval between acquire retries. Default is 500ms.
func WithRetryTimeout ¶
WithRetryTimeout sets the total time to retry acquiring a held lock. Default is 5s.
type ResourceLocker ¶
type ResourceLocker struct {
// contains filtered or unexported fields
}
ResourceLocker acquires and releases distributed locks backed by Kubernetes Lease resources. Each lock is a single Lease object in the configured namespace. The locker creates the Lease on acquire and deletes it on release, so no Lease resources linger after normal operation.
func NewResourceLocker ¶
func NewResourceLocker(c client.Client, namespace string, opts ...Option) *ResourceLocker
NewResourceLocker creates a ResourceLocker that manages Lease resources in the given namespace. Configure behaviour with functional options; the defaults are tuned for short-lived locks that protect a single API call.
func (*ResourceLocker) AcquireLock ¶
func (rl *ResourceLocker) AcquireLock(ctx context.Context, name, lockerID string) error
AcquireLock tries to acquire a Lease-backed lock identified by name.
The algorithm has three cases:
- Lease does not exist — create it and return (lock acquired).
- Lease exists but is expired — update it to claim ownership.
- Lease exists and is still valid — wait and retry until the timeout, then return ErrLockHeld.
Create and Update conflicts (another replica raced us) are retried transparently within the timeout window. The wait between retries is context-aware: if ctx is cancelled, AcquireLock returns ctx.Err() immediately instead of blocking.
func (*ResourceLocker) ReleaseLock ¶
func (rl *ResourceLocker) ReleaseLock(ctx context.Context, name, lockerID string) error
ReleaseLock deletes the Lease if it is held by the given lockerID. If the Lease does not exist or is held by a different locker, this is a no-op. The holder check prevents a slow replica from accidentally releasing a lock that was already re-acquired by someone else.