Documentation
¶
Overview ¶
Package worklease provides lease-based work coordination for distributed systems.
worklease solves a different problem than distributed locking. Distributed locks answer: who owns this resource right now? worklease answers: when ownership changes, what does the new owner need to continue the work the previous owner started?
The library is built around three primitives:
- A Lease — a time-limited, named claim on a unit of work.
- A fencing token — a monotonically incrementing integer that prevents zombie writes from a worker that was slow, not dead.
- A checkpoint — progress state written atomically with lease renewal, so the last known state survives to the next owner.
Entry point ¶
Construct a Lease with New, backed by a github.com/aetomala/worklease/backend.Backend:
backend, err := postgres.New(db)
lease, err := worklease.New(backend, worklease.Config{
TTL: 30 * time.Second,
HolderID: workerID,
})
See the Lease interface for the full API.
What worklease is not ¶
worklease is not a distributed lock library, a workflow engine, or a general-purpose job queue. For mutual exclusion alone, use distlock or pglock. For durable workflow execution, use Temporal. For Kubernetes-native leader election, use client-go/leaderelection. The leader subpackage provides simplified single-work-item leadership, and the pool subpackage distributes a fixed set of work IDs across competing processes — both built on worklease's own Lease primitives.
Backends ¶
Two backends are included:
- github.com/aetomala/worklease/backend/postgres — PostgreSQL-backed, suitable for production use. Requires a running PostgreSQL instance and the worklease schema applied.
- github.com/aetomala/worklease/backend/memory — in-memory, suitable for unit tests within a single process.
Index ¶
- Constants
- Variables
- func HasWaitForLease(opts []AcquireOption) bool
- func LeaseWindow(ctx context.Context) (deadline time.Time, ok bool)
- type AcquireEvent
- type AcquireOption
- type Checkpoint
- type CheckpointEvent
- type Config
- type ExitMode
- type FencedEvent
- type ForgetEvent
- type Lease
- type LeaseObserver
- type NoopObserver
- func (NoopObserver) OnAcquire(_ context.Context, _ AcquireEvent)
- func (NoopObserver) OnCheckpoint(_ context.Context, _ CheckpointEvent)
- func (NoopObserver) OnFenced(_ context.Context, _ FencedEvent)
- func (NoopObserver) OnForget(_ context.Context, _ ForgetEvent)
- func (NoopObserver) OnReadCheckpoint(_ context.Context, _ ReadCheckpointEvent)
- func (NoopObserver) OnRelease(_ context.Context, _ ReleaseEvent)
- func (NoopObserver) OnRenew(_ context.Context, _ RenewEvent)
- type NoopVacuumObserver
- type Operation
- type ReadCheckpointEvent
- type ReleaseEvent
- type RenewEvent
- type RenewalOption
- type SweepEvent
- type SweepOptions
- type Token
- type Vacuum
- type VacuumConfig
- type VacuumObserver
Examples ¶
Constants ¶
const ( // ExitNone means there was no previous holder: the work ID was never // acquired, or its row was removed by Forget or Sweep. Inferred; Release // never accepts it. ExitNone = backend.ExitNone // ExitFinished means the run completed and the checkpoint is final state // for that run. The work ID may be acquired again. Sweep never deletes a // row whose last exit is ExitFinished, so release one-shot work with // ExitRetired instead. ExitFinished = backend.ExitFinished // ExitAbandoned means the holder stopped deliberately without completing, // on error, cancellation, or shutdown. The checkpoint is partial state. ExitAbandoned = backend.ExitAbandoned // ExitRetired means the work ID is complete permanently. A successor // should not redo the work. The row is eligible for Sweep. ExitRetired = backend.ExitRetired // ExitExpired means the lease expired with no recorded exit: a crash, a // partition, or a renewal window that ran out. The checkpoint is partial // state, and external effects may have happened after it. Inferred; // Release never accepts it. ExitExpired = backend.ExitExpired )
Exit modes. Callers must treat any value they do not recognize as ExitExpired, because modes may be added in later releases.
Variables ¶
var ( // ErrFenced is returned by Checkpoint, Renew, Release, ReadCheckpoint, and // Forget when the token no longer matches the stored lease or when no record // exists for the work ID. It is the same value as backend.ErrFenced. ErrFenced = backend.ErrFenced // ErrLeaseHeld is returned by Acquire when the lease for the work ID is held // and has not expired. It is the same value as backend.ErrLeaseHeld. ErrLeaseHeld = backend.ErrLeaseHeld // ErrLeaseExpired is returned by Renew when the lease has already expired, by // Release when the lease has expired or this holder already declared an exit, // and by Checkpoint only once this holder has declared an exit with Release. // It is the same value as backend.ErrLeaseExpired. ErrLeaseExpired = backend.ErrLeaseExpired // ErrLeaseWindowExhausted is set as the cancel cause of the renewal context // when the renewal goroutine exhausts the remaining lease window without a // successful renewal (goroutine lifecycle path 3). // Inspect via context.Cause(renewCtx) — not returned directly from any method. ErrLeaseWindowExhausted = errors.New(msgLeaseWindowExhausted) // ErrConfigInvalid is the parent sentinel for configuration errors: every // error worklease.New returns, ErrNilBackend wherever it is returned, // ErrRetentionRequired, and the configuration sentinels of the pool, worker, // and leader packages. Errors from other packages, such as the nil database // check of postgres.New, are not members. Match it with errors.Is. ErrConfigInvalid = errors.New("worklease: invalid configuration") // ErrNilBackend is returned by New and NewVacuum when the backend is nil, // and by Vacuum.Sweep on a Vacuum that NewVacuum did not build. It matches // ErrConfigInvalid. ErrNilBackend error = &configError{msg: msgNilBackend} )
Sentinel errors for Lease operations. ErrFenced, ErrLeaseHeld, and ErrLeaseExpired are the identical values of the sentinels of the same name in package backend, so errors.Is matches either name.
var ( // ErrInvalidExitMode is returned by Release when mode is not ExitFinished, // ExitAbandoned, or ExitRetired. It is the same value as // backend.ErrInvalidExitMode. ErrInvalidExitMode = backend.ErrInvalidExitMode // ErrRetire is returned, or wrapped, by a work function to declare that its // work ID is complete permanently. Runner.Run in package worker, Elect in // package leader, and Pool in package pool release the lease with // ExitRetired and report success. Pool also stops the slot. ErrRetire = errors.New(msgRetire) )
var ErrRetentionRequired error = &configError{msg: msgRetentionRequired}
ErrRetentionRequired is returned by Vacuum.Sweep when opts.Retention <= 0. It matches ErrConfigInvalid.
Functions ¶
func HasWaitForLease ¶ added in v0.3.0
func HasWaitForLease(opts []AcquireOption) bool
HasWaitForLease reports whether opts includes WithWaitForLease. Pool.New uses this to enforce that WithWaitForLease is not passed in Config.AcquireOptions at construction time.
func LeaseWindow ¶ added in v0.7.0
LeaseWindow returns the end of the lease window tracked by the renewal goroutine whose renewal context is ctx or the nearest ancestor of ctx. The window starts as the local start of the acquiring backend call plus TTL, and advances to the local start of each successful renewal plus TTL. It is measured on the local monotonic clock, so under a constant offset between the local and backend clocks it never exceeds the true expiry. The ok result is false when ctx does not descend from a renewal context, and once that renewal context is done: after fencing, an exhausted window, or cancellation of its parent. After stopRenewal the window stays valid and stops advancing.
Types ¶
type AcquireEvent ¶ added in v0.4.0
AcquireEvent carries the result of one backend acquire attempt. Duration is the duration of that backend call only — not the wait loop. Token is the zero value of Token if Err is non-nil.
type AcquireOption ¶
type AcquireOption func(*acquireConfig)
AcquireOption is a functional option for Acquire.
func WithPollInterval ¶
func WithPollInterval(d time.Duration) AcquireOption
WithPollInterval sets the interval at which Acquire polls when WithWaitForLease is active. If d is zero or negative, the default (2 * time.Second) is preserved.
func WithWaitForLease ¶
func WithWaitForLease() AcquireOption
WithWaitForLease configures Acquire to block and retry until a lease becomes available, rather than returning ErrLeaseHeld immediately.
type Checkpoint ¶ added in v0.6.0
type Checkpoint = backend.Checkpoint
Checkpoint is the last checkpointed state plus how the immediately previous holder exited. It is an alias for backend.Checkpoint.
type CheckpointEvent ¶ added in v0.4.0
CheckpointEvent carries the result of a Checkpoint call. Size is len(state) from the call site.
type Config ¶
type Config struct {
// TTL is the time-to-live for acquired leases. Required; New returns an
// error for zero, for a negative value, and for any value below 1ms.
TTL time.Duration
// HolderID is the identifier of the entity that will hold leases. Required; empty returns an error.
HolderID string
// Observer is the LeaseObserver that will be notified of lease events. Optional; nil defaults to NoopObserver.
Observer LeaseObserver
}
Config holds configuration for a Lease instance.
type ExitMode ¶ added in v0.6.0
ExitMode records how a lease holder left a lease. It is an alias for backend.ExitMode; the canonical definition lives in package backend because package backend cannot import package worklease.
type FencedEvent ¶ added in v0.4.0
FencedEvent carries the context of a fencing event. Called in addition to the operation-specific event — not instead of.
type ForgetEvent ¶ added in v0.7.0
ForgetEvent carries the result of a Forget call. Duration is the duration of the backend call.
type Lease ¶
type Lease interface {
// Acquire attempts to acquire a lease for the given workID. Returns ErrLeaseHeld
// if the lease for this workID is held and has not expired. If WithWaitForLease
// is set, blocks until the lease is available, polling at the configured interval.
// An empty workID returns an error that matches no sentinel, including
// ErrConfigInvalid.
Acquire(ctx context.Context, workID string, opts ...AcquireOption) (Token, error)
// Checkpoint persists state associated with the current lease. The caller must
// pass a valid Token obtained from Acquire. Returns ErrFenced if the
// token's holder ID or fencing token no longer matches the stored lease, including when the
// lease lapsed and another holder has since acquired it.
// Checkpoint returns ErrLeaseExpired, without writing, only once this holder has
// declared an exit with Release; a declared exit cannot be undone by a late
// write. Stop any background checkpoint loop when it sees ErrLeaseExpired.
// A lease whose TTL lapsed with no declared exit and no successor is not an
// error: the write succeeds and revives the lease.
// A nil or empty state clears the stored state: ReadCheckpoint then returns a
// nil State on every backend.
Checkpoint(ctx context.Context, token Token, state []byte) error
// Renew extends the lease expiration time. Returns ErrFenced if the token's
// holder ID or fencing token no longer matches the stored lease, or ErrLeaseExpired if the
// lease has already expired.
Renew(ctx context.Context, token Token) error
// Release records mode as this holder's exit and expires the lease
// immediately, so a successor can acquire without waiting for the TTL. The
// successor reads mode as Checkpoint.PrevExit. Mode must be ExitFinished,
// ExitAbandoned, or ExitRetired; any other value returns ErrInvalidExitMode
// without calling the backend or the observer. Returns ErrFenced if the
// lease was acquired by another holder or its record was removed, and
// ErrLeaseExpired if the lease has expired or this holder already declared an
// exit, even when no successor has acquired it. A lapsed holder cannot
// record an exit, so its successor sees ExitExpired. Call Release with the
// original ctx or a cleanup context, never the renewal context.
Release(ctx context.Context, token Token, mode ExitMode) error
// ReadCheckpoint returns the last checkpointed state and how the
// immediately previous holder exited. On a first acquisition State is nil
// and PrevExit is ExitNone. State is also nil after a Checkpoint with a nil
// or empty state, and is never a non-nil empty slice. PrevExit and
// PrevHolderID are fixed for the life of the lease. Returns ErrFenced if the
// token no longer matches the stored lease or if no row exists for the work
// ID, for example after Forget or Sweep.
ReadCheckpoint(ctx context.Context, token Token) (Checkpoint, error)
// StartRenewal begins automatic renewal of the lease at regular intervals.
// Returns a derived context and a stop function. The renewal context is
// cancelled if the parent context is cancelled, if the lease is fenced, or
// if the lease window closes before a renewal succeeds. Calling the stop
// function ends renewal without cancelling the renewal context, and it
// returns without waiting for an in-flight Renew call to finish.
// If Renew returns ErrLeaseExpired, storage has found the lease lapsed:
// renewal stops at once without retrying, and the renewal context's cause
// matches both ErrLeaseWindowExhausted and ErrLeaseExpired.
// LeaseWindow reports the current lease window from the renewal context.
StartRenewal(ctx context.Context, token Token, opts ...RenewalOption) (renewCtx context.Context, stopRenewal func())
// Forget permanently deletes the lease record for token's workID. Returns
// ErrFenced if the holder ID or fencing token no longer matches the stored lease, or if no
// record exists for token's workID. Unlike Release, the record is not left
// behind for a future ReadCheckpoint — it is gone. Use only when a work ID is
// permanently retired. Every call is reported to LeaseObserver.OnForget, and
// a fenced call also to OnFenced.
Forget(ctx context.Context, token Token) error
}
Lease defines the contract for acquiring, managing, and renewing leases on distributed work. Implementations are responsible for handling backend storage, fencing, and expiration logic. All methods are safe for concurrent use.
Lease is not a stable target for implementations outside this module: a minor release may add a method to it. A wrapper or fake that must satisfy Lease embeds the Lease interface so that it keeps compiling.
func New ¶
New returns a new Lease instance backed by the provided Backend. Every error it returns matches ErrConfigInvalid with errors.Is:
- ErrNilBackend if b is nil.
- "worklease: New: TTL is required" if cfg.TTL is zero.
- "worklease: New: HolderID is required" if cfg.HolderID is empty.
- "worklease: New: TTL must be positive, got <TTL>" if cfg.TTL is negative.
- "worklease: New: TTL must be at least 1ms, got <TTL>" if cfg.TTL is below 1ms.
The checks run in that order, and the first failing check is returned.
type LeaseObserver ¶ added in v0.2.0
type LeaseObserver interface {
// OnAcquire is called after every backend acquire attempt, successful or not —
// once per poll when WithWaitForLease is set. e.Duration is the duration of
// that attempt's backend call only — not the wait loop.
// e.Token is the zero value of Token if e.Err is non-nil.
OnAcquire(ctx context.Context, e AcquireEvent)
// OnCheckpoint is called after every Checkpoint attempt.
// If e.Err is ErrFenced, OnFenced is also called after this method returns.
OnCheckpoint(ctx context.Context, e CheckpointEvent)
// OnRenew is called after every Renew attempt.
// If e.Err is ErrFenced, OnFenced is also called after this method returns.
OnRenew(ctx context.Context, e RenewEvent)
// OnRelease is called after every Release attempt.
// If e.Err is ErrFenced, OnFenced is also called after this method returns.
OnRelease(ctx context.Context, e ReleaseEvent)
// OnReadCheckpoint is called after every ReadCheckpoint attempt.
// OnFenced is NOT called on ReadCheckpoint — ErrFenced surfaces via e.Err only.
OnReadCheckpoint(ctx context.Context, e ReadCheckpointEvent)
// OnForget is called after every Forget attempt.
// If e.Err is ErrFenced, OnFenced is also called after this method returns.
OnForget(ctx context.Context, e ForgetEvent)
// OnFenced is called when Checkpoint, Renew, Release, or Forget returns
// ErrFenced — not for ReadCheckpoint. Called in addition to the
// operation-specific callback — not instead of.
// e.Operation identifies which operation triggered the fencing event.
OnFenced(ctx context.Context, e FencedEvent)
}
LeaseObserver receives callbacks after each Lease operation. All methods are called synchronously. Implementations must not block or panic. The zero value of Config.Observer is nil; the library substitutes a no-op observer.
A minor release may add a method to LeaseObserver. Embed NoopObserver in an observer type so that it keeps compiling.
type NoopObserver ¶ added in v0.8.0
type NoopObserver struct{}
NoopObserver is a LeaseObserver that discards every event. The library substitutes it when Config.Observer is nil. Embed it in an observer type to implement only the methods of interest; the embedding type keeps compiling when a later release adds a method to LeaseObserver.
Example ¶
package main
import (
"context"
"fmt"
"sync/atomic"
"time"
"github.com/aetomala/worklease"
"github.com/aetomala/worklease/backend/memory"
)
// The acquireCounter type counts Acquire attempts and ignores every other event.
// Embedding worklease.NoopObserver supplies the other LeaseObserver methods.
type acquireCounter struct {
worklease.NoopObserver
n atomic.Int64
}
func (c *acquireCounter) OnAcquire(_ context.Context, _ worklease.AcquireEvent) {
c.n.Add(1)
}
func main() {
obs := &acquireCounter{}
lease, err := worklease.New(memory.New(), worklease.Config{
TTL: 30 * time.Second,
HolderID: "worker-1",
Observer: obs,
})
if err != nil {
fmt.Println("error:", err)
return
}
if _, err := lease.Acquire(context.Background(), "work-1"); err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("acquires:", obs.n.Load())
}
Output: acquires: 1
func (NoopObserver) OnAcquire ¶ added in v0.8.0
func (NoopObserver) OnAcquire(_ context.Context, _ AcquireEvent)
OnAcquire discards the event.
func (NoopObserver) OnCheckpoint ¶ added in v0.8.0
func (NoopObserver) OnCheckpoint(_ context.Context, _ CheckpointEvent)
OnCheckpoint discards the event.
func (NoopObserver) OnFenced ¶ added in v0.8.0
func (NoopObserver) OnFenced(_ context.Context, _ FencedEvent)
OnFenced discards the event.
func (NoopObserver) OnForget ¶ added in v0.8.0
func (NoopObserver) OnForget(_ context.Context, _ ForgetEvent)
OnForget discards the event.
func (NoopObserver) OnReadCheckpoint ¶ added in v0.8.0
func (NoopObserver) OnReadCheckpoint(_ context.Context, _ ReadCheckpointEvent)
OnReadCheckpoint discards the event.
func (NoopObserver) OnRelease ¶ added in v0.8.0
func (NoopObserver) OnRelease(_ context.Context, _ ReleaseEvent)
OnRelease discards the event.
func (NoopObserver) OnRenew ¶ added in v0.8.0
func (NoopObserver) OnRenew(_ context.Context, _ RenewEvent)
OnRenew discards the event.
type NoopVacuumObserver ¶ added in v0.8.0
type NoopVacuumObserver struct{}
NoopVacuumObserver is a VacuumObserver that discards every event. NewVacuum substitutes it when VacuumConfig.Observer is nil. Embed it in an observer type so that the embedding type keeps compiling when a later release adds a method to VacuumObserver.
func (NoopVacuumObserver) OnSweep ¶ added in v0.8.0
func (NoopVacuumObserver) OnSweep(_ context.Context, _ SweepEvent)
OnSweep discards the event.
type Operation ¶ added in v0.4.0
type Operation uint8
Operation identifies the Lease operation that triggered a fencing event. The zero value is not a valid Operation.
const ( // OperationCheckpoint identifies a Checkpoint call. OperationCheckpoint Operation = iota + 1 // OperationRenew identifies a Renew call. OperationRenew // OperationRelease identifies a Release call. OperationRelease // OperationForget identifies a Forget call. OperationForget )
Operation values for fencing events. The values start at 1 so that the zero value is not a valid Operation.
type ReadCheckpointEvent ¶ added in v0.4.0
type ReadCheckpointEvent struct {
Token Token
Duration time.Duration
PrevExit ExitMode
PrevHolderID string
Size int
Err error
}
ReadCheckpointEvent carries the result of a ReadCheckpoint call. Size is the length of the returned state; 0 if nil. PrevExit is ExitNone and PrevHolderID is empty when Err is non-nil.
type ReleaseEvent ¶ added in v0.4.0
ReleaseEvent carries the result of a Release call. Mode is the exit the caller declared. OnRelease is not called when Release rejects the mode with ErrInvalidExitMode.
type RenewEvent ¶ added in v0.4.0
RenewEvent carries the result of a Renew call. Attempt is 1 on the first attempt. The renewal goroutine increments Attempt on each retry attempt within the backoff loop. Direct calls to Renew from caller code always produce Attempt: 1. When the renewal goroutine abandons an in-flight attempt, Err is the error of the abandonment: context.Canceled on stopRenewal, the parent context's error on its cancellation, and context.DeadlineExceeded when the lease window closes. Duration then runs to the moment of abandonment.
type RenewalOption ¶
type RenewalOption func(*renewalConfig)
RenewalOption is a functional option for StartRenewal.
func WithRenewalBackoff ¶ added in v0.5.0
func WithRenewalBackoff(initial, maxInterval time.Duration, jitter float64) RenewalOption
WithRenewalBackoff configures the exponential backoff policy used by the renewal goroutine when Renew returns a non-fencing, non-nil error. The initial parameter is the first retry interval; maxInterval caps the interval after growth. The jitter parameter is a fraction in [0, 1]; the actual wait is drawn from [base, base+jitter*base]. Defaults: initial=100ms, max=5s, jitter=0.20. Clamping (in order): initial floors to 1ms if <= 0; max floors to 1ms if <= 0; jitter clamps to [0, 1]; finally initial caps at max if initial > max.
func WithRenewalInterval ¶
func WithRenewalInterval(d time.Duration) RenewalOption
WithRenewalInterval sets the time between renewal attempts. Default: TTL/2. Zero or negative values are ignored — the default is used silently.
type SweepEvent ¶ added in v0.7.0
type SweepEvent struct {
Options SweepOptions
Deleted int64
Duration time.Duration
Err error
}
SweepEvent carries the result of one Sweep backend call. Options holds the options passed to Sweep, Deleted the number of rows the backend reported deleted, and Duration the duration of the backend call.
type SweepOptions ¶ added in v0.6.0
type SweepOptions = backend.SweepOptions
SweepOptions configures a Vacuum.Sweep call. It is a type alias for backend.SweepOptions — the canonical definition lives in package backend to avoid an import cycle (package backend cannot import package worklease).
type Token ¶
type Token struct {
// contains filtered or unexported fields
}
Token represents a currently held lease. It is returned by Acquire and must be passed back to Checkpoint, Renew, Release, ReadCheckpoint, Forget, and StartRenewal. Renew and Checkpoint do not return a new Token — the same Token stays valid for the life of the lease. All fields are unexported; use accessor methods to read them. A Token is a value and is safe for concurrent use.
func NewToken ¶ added in v0.8.0
NewToken returns a Token holding the given fields, for tests and fakes that need a Token value without acquiring a lease. NewToken does not call a backend and does not validate its arguments. A Token it returns has no local lease window, so the window that StartRenewal bounds renewal by is already closed. Use Acquire to obtain a Token for a real lease.
Example ¶
package main
import (
"fmt"
"time"
"github.com/aetomala/worklease"
)
func main() {
expires := time.Date(2026, 1, 1, 12, 0, 0, 0, time.UTC)
token := worklease.NewToken("work-1", "worker-1", 7, expires)
fmt.Println(token.WorkID(), token.HolderID(), token.FencingToken(), token.ExpiresAt().Format(time.RFC3339))
}
Output: work-1 worker-1 7 2026-01-01T12:00:00Z
func (Token) ExpiresAt ¶
ExpiresAt returns the lease expiry recorded at acquisition, as reported by the backend's clock. It is not updated by Renew or Checkpoint. For a bound that reflects renewals, call LeaseWindow with the renewal context.
func (Token) FencingToken ¶
FencingToken returns the monotonically increasing token that prevents stale operations on the lease. If the lease is reassigned, the token changes.
type Vacuum ¶ added in v0.6.0
type Vacuum struct {
// contains filtered or unexported fields
}
Vacuum performs age-based bulk cleanup of lease rows. Sweep deletes rows released with ExitRetired once they are older than SweepOptions.Retention and, with SweepOptions.IncludeExpired, rows whose lease expired with no declared exit. Rows released with ExitFinished or ExitAbandoned, and rows currently held, are never deleted. A deleted row's checkpoint is gone: the next holder of that work ID sees ExitNone and empty state, and a holder whose row was deleted gets ErrFenced. Build a Vacuum with NewVacuum. A Vacuum is safe for concurrent use if its Backend and its VacuumObserver are.
func NewVacuum ¶ added in v0.6.0
func NewVacuum(b backend.Backend, cfg VacuumConfig) (*Vacuum, error)
NewVacuum returns a Vacuum backed by b. Returns ErrNilBackend if b is nil. The cfg argument may be the zero value.
func (*Vacuum) Sweep ¶ added in v0.6.0
Sweep deletes rows that are not currently held and were last updated more than opts.Retention ago: rows released with ExitRetired and, with opts.IncludeExpired, rows whose lease expired with no declared exit. It returns the number of rows the backend reported deleted. Sweep returns ErrNilBackend, without calling the backend or the observer, on a Vacuum that NewVacuum did not build, including a nil *Vacuum. It returns ErrRetentionRequired, also without either call, if opts.Retention <= 0. Otherwise it calls the backend, reports the outcome to the configured VacuumObserver, and returns the backend's result unchanged.
type VacuumConfig ¶ added in v0.7.0
type VacuumConfig struct {
// Observer receives the outcome of every Sweep that reaches the backend.
// Optional; nil installs a no-op observer.
Observer VacuumObserver
}
VacuumConfig configures a Vacuum.
type VacuumObserver ¶ added in v0.7.0
type VacuumObserver interface {
// OnSweep is called after every Sweep backend call, successful or not. It
// is not called when Sweep returns ErrNilBackend or ErrRetentionRequired,
// since those return before the backend is called.
OnSweep(ctx context.Context, e SweepEvent)
}
VacuumObserver receives a callback after each Vacuum.Sweep backend call. It is called synchronously. Implementations must not block or panic.
A minor release may add a method to VacuumObserver. Embed NoopVacuumObserver in an observer type so that it keeps compiling.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package backend defines the storage contract that worklease backends implement, the types shared across it, and the sentinel errors that backends return.
|
Package backend defines the storage contract that worklease backends implement, the types shared across it, and the sentinel errors that backends return. |
|
conformance
Package conformance provides a backend-agnostic Ginkgo specification that any worklease backend must satisfy.
|
Package conformance provides a backend-agnostic Ginkgo specification that any worklease backend must satisfy. |
|
memory
Package memory implements the worklease Backend in process memory.
|
Package memory implements the worklease Backend in process memory. |
|
postgres
Package postgres implements the worklease Backend on PostgreSQL.
|
Package postgres implements the worklease Backend on PostgreSQL. |
|
Package checkpoint provides typed serialization helpers for worklease checkpoints: the Codec interface, a JSON codec, and the generic Encode and Decode functions.
|
Package checkpoint provides typed serialization helpers for worklease checkpoints: the Codec interface, a JSON codec, and the generic Encode and Decode functions. |
|
internal
|
|
|
testutil
Package testutil is a generated GoMock package.
|
Package testutil is a generated GoMock package. |
|
Package leader runs a function while holding a worklease lease, so that one process at a time acts as the leader for a work ID.
|
Package leader runs a function while holding a worklease lease, so that one process at a time acts as the leader for a work ID. |
|
Package pool runs a work function for each of a set of work IDs, holding a worklease lease while each one runs.
|
Package pool runs a work function for each of a set of work IDs, holding a worklease lease while each one runs. |
|
Package worker runs a work function under a worklease lease: it acquires the lease, passes the prior checkpoint to the function, and renews the lease while the function runs.
|
Package worker runs a work function under a worklease lease: it acquires the lease, passes the prior checkpoint to the function, and renews the lease while the function runs. |