scheduler

package
v0.1.0-alpha.8 Latest Latest
Warning

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

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

Documentation

Overview

Package scheduler runs on the leader and reconciles desired replica counts into Assignments: it decides WHAT should run WHERE, writing only desired state (agents converge it, T-15). The red/green deployment orchestrator (T-26) drives green placement through the same helpers.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Place

func Place(st *state.Store, rel *zatterav1.Release, envID string, n int, exclude map[string]bool) ([]string, error)

Place selects up to n nodes to run replicas of rel (its frozen ServiceSpec) for environment envID.

It is a PURE function over state (no I/O), so it is fully table-testable. Capacity is judged by RESERVATIONS (sum of RUN assignments' declared resources), not live usage. `exclude` skips nodes entirely — the red/green orchestrator uses it to place a green set beside blue and to avoid retrying a candidate that already failed. Returns fewer than n plus an error when filters/capacity cannot satisfy the request.

Types

type Autoscaler

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

Autoscaler runs on the leader and adjusts each environment's effective_replicas from observed CPU/memory/RPS against its Autoscale targets (spec F7). It only writes effective_replicas; the scheduler (T-23) converges the replica count into assignments.

func NewAutoscaler

func NewAutoscaler(store *raftstore.Store, live LiveView, clk clock.Clock, log *slog.Logger) *Autoscaler

NewAutoscaler builds the autoscaler.

func (*Autoscaler) Run

func (a *Autoscaler) Run(ctx context.Context)

Run evaluates while this node leads, resetting hold timers on each term.

type BuildDialer

type BuildDialer interface {
	RunBuild(ctx context.Context, node *zatterav1.Node, req *clusterv1.RunBuildRequest) (BuildStream, error)
}

BuildDialer opens a RunBuild stream to a builder node's AgentLocalService (over the mesh in production; a fake in tests).

type BuildDispatcher

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

BuildDispatcher assigns QUEUED builds to builder nodes, streams their events, and records the outcome durably. It runs on the leader.

func NewBuildDispatcher

func NewBuildDispatcher(store *raftstore.Store, clk clock.Clock, dial BuildDialer, cfg BuildDispatcherConfig, log *slog.Logger) *BuildDispatcher

NewBuildDispatcher constructs the dispatcher.

func (*BuildDispatcher) BuildLog

func (d *BuildDispatcher) BuildLog(id string) []string

BuildLog returns the buffered log lines for a build (best-effort, in-memory).

func (*BuildDispatcher) Run

func (d *BuildDispatcher) Run(ctx context.Context)

Run dispatches builds while this node leads, resuming on re-election.

func (*BuildDispatcher) SetBuilderTimeout

func (d *BuildDispatcher) SetBuilderTimeout(t time.Duration)

SetBuilderTimeout overrides the no-event builder-lost timeout (tests use a short window; production keeps the default).

type BuildDispatcherConfig

type BuildDispatcherConfig struct {
	// SourceURLBase is the control-plane blob endpoint prefix, e.g.
	// "https://10.90.0.1:8443/internal/blobs/"; the tarball digest is appended.
	SourceURLBase string
	// RegistryAddr is the embedded registry "host:port" images push to.
	RegistryAddr string
	// LocalLoad means builders load images into the local Docker store instead
	// of pushing to the registry (single-node/dev, T-54); deploy by tag, not by
	// registry digest, since a loaded image has no registry digest.
	LocalLoad bool
}

BuildDispatcherConfig carries the addresses the dispatcher stamps into build requests: where the builder fetches source and where it pushes the image.

type BuildStream

type BuildStream interface {
	Recv() (*clusterv1.BuildEvent, error)
}

BuildStream is the receive side of an AgentLocalService.RunBuild stream.

type GRPCBuildDialer

type GRPCBuildDialer struct {
	Connect func(ctx context.Context, node *zatterav1.Node) (*grpc.ClientConn, error)
}

GRPCBuildDialer is the production BuildDialer: it dials a builder node's AgentLocalService over the mesh with node mTLS. Connect supplies the per-node client connection (node cert + mesh address); it stays injectable so the daemon owns the transport details.

func (GRPCBuildDialer) RunBuild

RunBuild opens the stream, keeping the connection alive for its lifetime.

type LiveView

type LiveView interface {
	Snapshot() []livestate.NodeState
}

LiveView is the slice of livestate the autoscaler reads: the current live sample of every connected node.

type Orchestrator

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

Orchestrator drives red/green Deployments through their phase machine on the leader. Every arm is idempotent and every transition is a single Apply, so a leader failover resumes from durable state (never in-memory progress).

func NewOrchestrator

func NewOrchestrator(store *raftstore.Store, clk clock.Clock, log *slog.Logger) *Orchestrator

NewOrchestrator builds the deployment orchestrator.

func (*Orchestrator) Run

func (o *Orchestrator) Run(ctx context.Context)

Run reconciles deployments while this node leads, resuming on re-election.

func (*Orchestrator) SetDrainWindow

func (o *Orchestrator) SetDrainWindow(d time.Duration)

SetDrainWindow overrides the blue-drain window (0 restores the default).

type RegistrySweeper

type RegistrySweeper interface {
	UntagAndSweep(repo, tag string) error
}

RegistrySweeper untags an image and reclaims blobs it solely referenced. The daemon wires this to the local registry (the sweep runs on the control node that hosts the blobs, never over the mesh).

type Retention

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

Retention prunes old releases (and their registry images) plus stale source tarballs on the leader.

func NewRetention

func NewRetention(store *raftstore.Store, clk clock.Clock, sweeper RegistrySweeper, uploadsDir string, log *slog.Logger) *Retention

NewRetention constructs the retention controller.

func (*Retention) Run

func (r *Retention) Run(ctx context.Context)

Run sweeps hourly while this node leads.

type RouteBuilder

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

RouteBuilder builds a global RouteSnapshot from cluster state and fans it out to WatchRoutes subscribers. Every control node builds the same snapshot from its replicated state (a pure function of state), so any control node can serve the stream — no leader gating needed.

func NewRouteBuilder

func NewRouteBuilder(store *raftstore.Store, clk clock.Clock, domain string, log *slog.Logger) *RouteBuilder

NewRouteBuilder constructs the route builder. domain is cfg.Domain (empty → no implicit cluster subdomains).

func (*RouteBuilder) Current

func (b *RouteBuilder) Current() *clusterv1.RouteSnapshot

Current returns the latest snapshot.

func (*RouteBuilder) Run

func (b *RouteBuilder) Run(ctx context.Context)

Run watches routing-relevant state and rebuilds (debounced) plus on a 15s tick, fanning each snapshot out to subscribers.

func (*RouteBuilder) Subscribe

func (b *RouteBuilder) Subscribe() (int, <-chan *clusterv1.RouteSnapshot)

Subscribe registers a WatchRoutes consumer; Unsubscribe with the returned id.

func (*RouteBuilder) Unsubscribe

func (b *RouteBuilder) Unsubscribe(id int)

Unsubscribe removes a subscriber.

type ScaleToZero

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

ScaleToZero cools an idle scale-to-zero environment down to zero replicas (T-69). It runs on the leader, reads per-env request activity from proxy heartbeats (livestate), and sets effective_replicas=0 once an env has been idle past its idle_timeout — the scheduler then stops the replicas. Waking a cold env back up is the activator's job (T-70); this loop only scales down.

func NewScaleToZero

func NewScaleToZero(store *raftstore.Store, live LiveView, clk clock.Clock, log *slog.Logger) *ScaleToZero

NewScaleToZero builds the loop.

func (*ScaleToZero) Run

func (s *ScaleToZero) Run(ctx context.Context)

Run evaluates while this node leads.

type Scheduler

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

Scheduler is the leader-only placement loop.

func New

func New(store *raftstore.Store, clk clock.Clock, log *slog.Logger) *Scheduler

New builds the scheduler.

func (*Scheduler) Run

func (s *Scheduler) Run(ctx context.Context)

Run evaluates while this node is the leader, stopping cleanly on leadership loss and resuming when re-elected. Blocks until ctx is canceled.

type Serverless

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

Serverless autoscales max_concurrency environments off in-flight request counts (T-71): desired = ceil(total_inflight / max_concurrency), clamped to [floor, max] where floor is 0 for scale_to_zero envs (idle cools to zero, the activator wakes them) else replicas.min. It owns these envs instead of the resource autoscaler (T-61) and the scale-to-zero loop (T-69).

func NewServerless

func NewServerless(store *raftstore.Store, live LiveView, clk clock.Clock, log *slog.Logger) *Serverless

NewServerless builds the loop.

func (*Serverless) Run

func (s *Serverless) Run(ctx context.Context)

Run evaluates while this node leads.

type SnapshotDispatcher

type SnapshotDispatcher interface {
	Snapshot(ctx context.Context, vol *zatterav1.Volume) error
	Prune(ctx context.Context, vol *zatterav1.Volume, deadSnapshotIDs []string) error
}

SnapshotDispatcher performs the node-side snapshot work the leader schedules: Snapshot dispatches a snapshot of the volume to its node; Prune deletes the given snapshots' manifest objects and garbage-collects orphaned chunks.

type SnapshotScheduler

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

SnapshotScheduler fires scheduled volume snapshots (SnapshotPolicy.schedule) on the leader and enforces keep_last retention.

func NewSnapshotScheduler

func NewSnapshotScheduler(store *raftstore.Store, disp SnapshotDispatcher, clk clock.Clock, log *slog.Logger) *SnapshotScheduler

NewSnapshotScheduler builds the scheduler.

func (*SnapshotScheduler) Run

func (s *SnapshotScheduler) Run(ctx context.Context)

Run evaluates while this node leads.

Jump to

Keyboard shortcuts

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