sweep

package
v0.0.6 Latest Latest
Warning

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

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

Documentation

Overview

Package sweep is the catalog-mode worker engine (spec 2026-07-03, D5): instead of boot-time loops per shard, a bounded pool sweeps the tenant catalog — each ACTIVE tenant's database gets a single maintenance pass (relay the outbox, materialize quiet documents, compact due logs) under that database's own advisory-lock claim, so any number of worker replicas cooperate without duplicate work.

Idle accounting keeps the fleet cheap: a tenant whose pass did no work backs off exponentially (base 5s, cap 5min, jittered) in a decaying in-memory table, while a wake nudge (published by the facade write path) resets the backoff so active tenants get sub-second latency without polling everyone.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Workers bounds concurrent tenant sweeps (default 16).
	Workers int
	// ScanInterval is the pass cadence when nothing wakes the engine
	// (default 1s — the poll floor for busy tenants).
	ScanInterval time.Duration
	// SweepTimeout bounds one tenant's maintenance pass (default 1min) so
	// a hung database cannot stall the pool slot forever.
	SweepTimeout time.Duration
	// BackoffBase is the first idle backoff (default 5s).
	BackoffBase time.Duration
	// BackoffCap is the idle backoff ceiling (default 5min).
	BackoffCap time.Duration
	// CompactEvery is the per-tenant document-compaction cadence
	// (default 30s, mirroring the static plane's DocCompactInterval).
	CompactEvery time.Duration
	// MinVersion skips tenants recorded below the binary's migration
	// floor ("" = no gate). The directory enforces the same floor for
	// serving; this keeps the sweeper from burning passes on tenants it
	// cannot acquire anyway.
	MinVersion string
	// OnPass observes each pass's stats (metrics). Called from Pass.
	OnPass func(Stats)
	// OnError observes per-tenant sweep failures (logging/metrics).
	OnError func(tenantID string, err error)
	// Now is the injectable clock (tests).
	Now func() time.Time
	// Jitter returns [0,1) scaling the idle backoff (tests inject 1.0
	// for determinism). Default: equal jitter via math/rand.
	Jitter func() float64
}

Config tunes the engine. Zero values take the documented defaults.

type Engine

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

Engine schedules tenant sweeps off the catalog.

func New

func New(cat catalog.Catalog, sweep TenantSweeper, cfg Config) *Engine

New builds an engine over the catalog and the per-tenant sweep seam.

func (*Engine) OnErrorSafe

func (e *Engine) OnErrorSafe(tenantID string, err error)

OnErrorSafe shields the engine from a panicking observer.

func (*Engine) Pass

func (e *Engine) Pass(ctx context.Context) Stats

Pass runs one full scan-and-sweep: list the catalog, dispatch every due tenant to the bounded pool, wait for the dispatched sweeps, and report. Failures back the tenant off and never abort the pass.

func (*Engine) Run

func (e *Engine) Run(ctx context.Context) error

Run passes until ctx ends: every ScanInterval, or immediately on a wake.

func (*Engine) SetSweepFn

func (e *Engine) SetSweepFn(fn TenantSweeper)

SetSweepFn swaps the sweep seam (tests/benchmarks).

func (*Engine) TrackedTenants

func (e *Engine) TrackedTenants() int

TrackedTenants reports the decaying table's size (tests/metrics).

func (*Engine) Wake

func (e *Engine) Wake(tenantID string)

Wake marks a tenant due immediately (resetting its idle backoff) and nudges the run loop — the write path publishes this so a busy tenant is relayed within one pass instead of one backoff window.

type Maintainer

type Maintainer interface {
	Sweep(ctx context.Context, compact bool) (Result, error)
}

Maintainer is one shard's single-pass worker surface: claim the shard's advisory locks (non-blocking) and, where won, run one maintenance pass. compact asks for the (heavier) document-log compaction sweep too.

type Result

type Result struct {
	// Relayed is the number of outbox envelopes published.
	Relayed int
	// Materialized is the number of quiet documents materialized.
	Materialized int
	// Compacted is the number of document logs compacted.
	Compacted int
	// Claimed reports whether this replica won the shard's work claims;
	// a false is a clean skip (another replica holds the tenant).
	Claimed bool
}

Result reports what one tenant maintenance pass did.

func (Result) Busy

func (r Result) Busy() bool

Busy reports whether the pass found work — a busy tenant is swept again on the very next pass instead of backing off.

type Stats

type Stats struct {
	// Duration is the pass's wall-clock time (by the engine's clock).
	Duration time.Duration
	// Scanned is every catalog entry seen.
	Scanned int
	// Eligible is the active, version-current subset.
	Eligible int
	// Swept is how many tenants had a maintenance pass dispatched.
	Swept int
	// Busy is how many sweeps found work.
	Busy int
	// Errors is how many sweeps failed.
	Errors int
}

Stats summarizes one engine pass.

type TenantSweeper

type TenantSweeper func(ctx context.Context, tenantID string, compact bool) (Result, error)

TenantSweeper resolves a tenant to its shard and runs one maintenance pass against it — the seam between this engine (pure scheduling) and the routing/adapter stack.

Jump to

Keyboard shortcuts

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