Help us shape the future of Go! Take the 2026 Go Developer Survey

gatedtick

package
v0.5.8 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: Apache-2.0 Imports: 4 Imported by: 0

Documentation

Overview

Package gatedtick runs the control plane's periodic background cycles: a ticker gated on scheduler leadership (the pod reconciler, the staging GC, the warm-pool reconcile, the retention janitor), the leader-bounded context one cycle of such a loop runs under, and the panic isolation every periodic loop shares.

Index

Constants

View Source
const LeaderTickPoll = time.Second

LeaderTickPoll is how often a running leader-gated cycle re-checks leadership (RunLeaderTick). The leadership watch polls every 5 seconds, so one second adds little to how long a step-down takes to stop the cycle.

Variables

This section is empty.

Functions

func Run

func Run(ctx context.Context, name string, ticks <-chan time.Time, leading func() bool, logger *slog.Logger, fn func())

Run is the loop of Start with the tick source injected, so the leadership gate is testable without a real timer. Each cycle is panic-isolated by SafeCycle. A tick that arrives while not leading is dropped, not queued.

func RunLeaderTick

func RunLeaderTick(ctx context.Context, name string, budget, poll time.Duration, leading func() bool, logger *slog.Logger, fn func(context.Context) error)

RunLeaderTick runs one cycle of a leader-gated loop that mutates cluster state (the warm-pool reconcile, the staging GC) under a context that ends at the cycle's budget or as soon as leading() reports false (#1602). The gated ticker only checks leadership when a tick starts, so without this a cycle in progress at a step-down kept creating and deleting pods next to the new leader's own loop, and one database call hung on a dead connection could hold it indefinitely. Both loops are level-triggered, so a cycle cut short is finished by the next one. A nil leading means always leading. An error is logged, except once the parent context is done (shutdown).

func RunOrKick

func RunOrKick(ctx context.Context, name string, ticks <-chan time.Time, kicks <-chan struct{}, minKickGap time.Duration, leading func() bool, logger *slog.Logger, fn func())

RunOrKick is Run that also runs the cycle on a signal from kicks (event-driven warm-pool refill), under the same leadership gate. A nil kicks channel never fires, which is exactly Run. A kicked run starts no sooner than minKickGap after the previous run, so a burst of events (a deploy draining many workers) costs one reconcile instead of one per event; kicks that arrive meanwhile coalesce into it. Ticks are never delayed.

func SafeCycle

func SafeCycle(name string, logger *slog.Logger, fn func())

SafeCycle runs one iteration of a periodic background loop, recovering any panic so a single bad cycle logs and is retried next tick instead of crashing the goroutine (and, since an unrecovered panic in any goroutine aborts the program, the whole control plane). It changes no behavior on the happy path.

func Start

func Start(ctx context.Context, name string, interval time.Duration, leading func() bool, logger *slog.Logger, fn func())

Start runs fn every interval on a background goroutine, but only while leading() reports this instance holds leadership. It stops when ctx is done. The pod reconciler and staging GC mutate cluster state, so at replicaCount>1 they must run on the leader alone (ADR 0009/0031); a nil gate means "always run" (single-replica / no election).

Types

This section is empty.

Jump to

Keyboard shortcuts

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