coord

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 13, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package coord holds leases for work that must run in one process at a time — the sweeper, and the ingest processes' shard claim membership. A lease is taken with TryAcquire and held as a Term until it is resigned, its coordinator is closed, or the backend reports it lost; RunElected drives a leader loop over one. Local is the in-process implementation; a distributed one lives with the connection it rides on (a NATS KV bucket in internal/mq), so this package imports only the standard library.

Every implementation runs the shared suite in coordtest.

Index

Constants

View Source
const RetryPeriod = 2 * time.Second

RetryPeriod is how often a candidate campaigns for a lease it does not hold (client-go's leader-election default).

Variables

View Source
var (
	// ErrHeld is TryAcquire's answer when the lease is live under another
	// holder — or under this coordinator already.
	ErrHeld = errors.New("coord: lease held")
	// ErrLost is what Term.Err wraps when the backend ended the term:
	// renewal failed past its deadline, or another holder took the lease.
	ErrLost = errors.New("coord: lease lost")
	// ErrClosed is TryAcquire's answer once the coordinator is closed.
	ErrClosed = errors.New("coord: coordinator closed")
)

Functions

func RunElected

func RunElected(ctx context.Context, c Coordinator, name string, retry time.Duration,
	fn func(ctx context.Context, term Term) error,
) error

RunElected blocks until ctx is done, running fn only while this process holds the named lease. It campaigns every retry, runs fn with a context canceled when the term ends, resigns when fn returns, and campaigns again. An error fn returns while its term is live is returned — fatal to the caller, like any component's; one it returns on its way out of an ended term is its stop, not a failure. ErrHeld and a lost term are the election working. A failed campaign is logged and retried, since the backend may be briefly unreachable; only ErrClosed ends the loop early.

Types

type Coordinator

type Coordinator interface {
	// TryAcquire takes the named lease if nobody holds a live one and keeps
	// it until Resign, Close, or loss; ctx bounds the call, not the term.
	// ErrHeld when the lease is live, including under this coordinator.
	TryAcquire(ctx context.Context, name string) (Term, error)
	// Close resigns every term this coordinator holds (best effort, within
	// ctx); TryAcquire returns ErrClosed from then on. Safe to call again.
	Close(ctx context.Context) error
}

Coordinator hands out named leases.

type Local

type Local struct {
	// contains filtered or unexported fields
}

Local is the in-process Coordinator: the first TryAcquire of a name wins and the term never expires, so a single process behaves exactly as it would with no coordination at all. Construct with NewLocal.

func NewLocal

func NewLocal() *Local

NewLocal returns a Coordinator over a lease table of its own.

func (*Local) Close

func (l *Local) Close(context.Context) error

Close implements Coordinator.

func (*Local) Held

func (l *Local) Held(ctx context.Context, name string) (bool, error)

Held implements Observer.

func (*Local) Peer

func (l *Local) Peer() *Local

Peer returns another Coordinator over the same lease table, as a second process would hold one over a shared backend: it contends for the same names and closes independently.

func (*Local) TryAcquire

func (l *Local) TryAcquire(ctx context.Context, name string) (Term, error)

TryAcquire implements Coordinator.

type Observer

type Observer interface {
	// Held reports whether the named lease is live under any holder, this
	// coordinator included, judged as TryAcquire would judge it: false for
	// a lease TryAcquire could take now.
	Held(ctx context.Context, name string) (bool, error)
}

Observer is implemented by a Coordinator that can tell whether a lease is held without campaigning for it: how a set of leases works out how many holders are live (the ingest processes count their peers this way).

type Term

type Term interface {
	Name() string
	// Token is the fencing token: strictly greater than every earlier
	// term's token for the same name on the same backend. Anything that
	// needs exclusivity, not just mostly-one-at-a-time, must check it
	// against what it writes: a holder that stalls past the lease duration
	// can overlap its successor.
	Token() uint64
	// Done closes when the term ends: resigned, its coordinator closed, or
	// lost. Work under the lease must stop promptly.
	Done() <-chan struct{}
	// Err is why Done closed: nil after Resign or Close, wrapping ErrLost
	// after a loss. Nil while the term is live.
	Err() error
	// Resign ends the term and frees the lease for the next candidate. A
	// term that has already ended resigns as a no-op.
	Resign(ctx context.Context) error
}

Term is one holding of a lease.

Directories

Path Synopsis
Package coordtest is the behavior every coord.Coordinator must share, as one suite each implementation runs against its own backend.
Package coordtest is the behavior every coord.Coordinator must share, as one suite each implementation runs against its own backend.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL