Documentation
¶
Overview ¶
Package liblease implements a cooperative, time-bounded file lease: a single-holder lock backed by an ordinary file, not an OS primitive. The file records who holds the lease and until when; a challenger may take over only once the lease has expired.
It is intentionally OS-agnostic — just a JSON file with atomic writes — so it behaves identically on Linux, macOS, and Windows.
A lease gives liveness, not safety, on its own. The holder MUST renew before expiry and MUST stop touching protected state if it cannot (see Expired): a process paused longer than the TTL can be taken over while it still believes it holds the lease. Protect critical operations by also checking the holder's InstanceID (a fencing token) so a revived stale holder cannot act.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrHeld = errors.New("liblease: lease is held by another instance")
ErrHeld is returned by Acquire when a live (unexpired) lease is held by a different instance.
var ErrLost = errors.New("liblease: lease was taken over by another instance")
ErrLost is returned by Renew when the lease has been taken over by another instance — the caller is no longer the holder.
Functions ¶
This section is empty.
Types ¶
type Lease ¶
type Lease struct {
// contains filtered or unexported fields
}
Lease is a held lease handle. It is not safe for concurrent use; call Renew from a single goroutine.
func Acquire ¶
Acquire claims the lease at path for ttl. It succeeds when the lease is free, expired, or unreadable, and fails with ErrHeld when a different instance holds a still-valid lease. On success the caller must Renew before ttl elapses and Release on shutdown.
func (*Lease) Expired ¶
Expired reports whether this holder's lease has lapsed based on its last successful Renew. A holder should use it to self-fence: if Expired is true, stop touching protected state — a takeover may have happened.
func (*Lease) InstanceID ¶
InstanceID returns this holder's fencing token.
type Record ¶
type Record struct {
InstanceID string `json:"instance_id"`
PID int `json:"pid"`
Host string `json:"host"`
AcquiredAt time.Time `json:"acquired_at"`
RenewedAt time.Time `json:"renewed_at"`
TTL time.Duration `json:"ttl"`
Meta map[string]string `json:"meta,omitempty"`
}
Record is the on-disk lease state. PID and Host are informational (the lease is enforced by TTL, not by process checks); InstanceID is the fencing token. Meta carries optional holder-supplied discovery data — e.g. the endpoint a serving owner advertises to followers — so "who and where" stays one atomic read.