scaling

package
v0.1.21 Latest Latest
Warning

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

Go to latest
Published: Mar 18, 2026 License: MIT Imports: 9 Imported by: 0

Documentation

Overview

Package scaling provides the policy engine for adaptive worker scaling. The policy evaluates system and pool metrics and produces scaling decisions; it does not execute them. Separation keeps the logic testable in isolation.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Validate

func Validate(cfg PolicyConfig) error

Validate checks that cfg contains internally consistent values.

Types

type Action

type Action int

Action represents a scaling decision type.

const (
	// Hold means no change to worker count.
	Hold Action = iota
	// ScaleUp means add workers.
	ScaleUp
	// ScaleDown means remove workers.
	ScaleDown
)

func (Action) String

func (a Action) String() string

String returns a human-readable name for the action.

type Autoscaler

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

Autoscaler is a long-running goroutine that periodically evaluates the scaling policy and applies the resulting decision to the pool. Start it with Run(ctx) and cancel the context to shut it down.

func NewAutoscaler

func NewAutoscaler(policy *ThresholdPolicy, pool PoolScaler, collector SystemCollector, logger *zap.Logger) *Autoscaler

NewAutoscaler creates an Autoscaler wired to the given policy, pool, and system collector. Scaling events are stored in an internal rolling buffer (capacity 100) accessible via Events(). Call SetPersister to additionally write events to durable storage.

func (*Autoscaler) Events

func (a *Autoscaler) Events() []models.ScalingEvent

Events returns recent scaling events from the in-memory buffer, newest first.

func (*Autoscaler) PolicyConfig

func (a *Autoscaler) PolicyConfig() PolicyConfig

PolicyConfig returns the policy configuration used by this autoscaler.

func (*Autoscaler) Run

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

Run starts the evaluation loop. It blocks until ctx is cancelled, then returns ctx.Err(). The loop evaluates the policy at the configured interval and applies any non-Hold decision to the pool.

func (*Autoscaler) SetControlReader

func (a *Autoscaler) SetControlReader(r ScalingControlReader)

SetControlReader attaches an optional store for reading manual scaling overrides. When set, the autoscaler checks for pause/set commands before each evaluation.

func (*Autoscaler) SetPersister

func (a *Autoscaler) SetPersister(p EventPersister)

SetPersister attaches an optional durable store for scaling events. When set, each scale event is also saved via p.SaveScalingEvent so events survive process restarts and are visible to other processes (e.g. serve).

type Decision

type Decision struct {
	// Action is the recommended scaling action.
	Action Action
	// Delta is the number of workers to add (ScaleUp) or remove (ScaleDown).
	// Zero for Hold decisions.
	Delta int
	// Reason is a human-readable explanation suitable for logs and the dashboard.
	Reason string
	// Confidence is a 0–1 score reflecting how many signals agree.
	// Higher means more signals agree; lower means ambiguous.
	Confidence float64
}

Decision is the output of a policy evaluation.

type EventBuffer

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

EventBuffer is a fixed-capacity ring buffer of ScalingEvents. Oldest events are dropped when the buffer is full. All methods are safe for concurrent use.

func NewEventBuffer

func NewEventBuffer(maxLen int) *EventBuffer

NewEventBuffer creates an EventBuffer with the given maximum capacity. If maxLen <= 0, it defaults to 100.

func (*EventBuffer) Add

func (b *EventBuffer) Add(e models.ScalingEvent)

Add appends an event to the buffer. If the buffer is at capacity the oldest event is evicted to make room.

func (*EventBuffer) Events

func (b *EventBuffer) Events() []models.ScalingEvent

Events returns a copy of all stored events in newest-first order.

type EventPersister

type EventPersister interface {
	SaveScalingEvent(ctx context.Context, e models.ScalingEvent) error
}

EventPersister is an optional interface for durable event storage. store.SQLiteStore satisfies this interface when scaling_events are enabled.

type Policy

type Policy interface {
	Evaluate(pool metrics.PoolSnapshot, sys metrics.SystemSnapshot) Decision
}

Policy evaluates metrics and returns a scaling Decision.

type PolicyConfig

type PolicyConfig struct {
	// Enabled controls whether the policy produces non-Hold decisions.
	// When false, Evaluate always returns Hold.
	Enabled bool `yaml:"enabled"`
	// MinWorkers is the minimum worker count the policy will recommend.
	MinWorkers int `yaml:"min_workers"`
	// MaxWorkers is the maximum worker count the policy will recommend.
	MaxWorkers int `yaml:"max_workers"`
	// EvaluationInterval is a hint for the autoscaler loop; not enforced here.
	EvaluationInterval time.Duration `yaml:"evaluation_interval"`
	// CooldownAfterScale is the minimum time between consecutive scale events.
	// Prevents oscillation.
	CooldownAfterScale time.Duration `yaml:"cooldown_after_scale"`
	// ScaleUp holds the scale-up thresholds.
	ScaleUp ScaleUpConfig `yaml:"scale_up"`
	// ScaleDown holds the scale-down thresholds.
	ScaleDown ScaleDownConfig `yaml:"scale_down"`
}

PolicyConfig holds all configurable thresholds for ThresholdPolicy.

func DefaultPolicyConfig

func DefaultPolicyConfig() PolicyConfig

DefaultPolicyConfig returns a conservative default configuration.

func LoadConfigFile

func LoadConfigFile(path string) (PolicyConfig, error)

LoadConfigFile reads a YAML config file and returns the scaling policy configuration. If the file does not exist, DefaultPolicyConfig is returned. CLI flag overrides should be applied by the caller after this call.

type PoolScaler

type PoolScaler interface {
	Snapshot() metrics.PoolSnapshot
	AddWorkers(n int) error
	RemoveWorkers(n int) int
	Workers() int
}

PoolScaler is the interface the autoscaler uses to inspect and resize the pool. agent.Pool satisfies this interface.

type ScaleDownConfig

type ScaleDownConfig struct {
	// IdleWorkerThreshold is the minimum number of idle workers required to consider
	// scaling down.
	IdleWorkerThreshold int `yaml:"idle_worker_threshold"`
	// IdleDuration is how long idle workers must exceed IdleWorkerThreshold before
	// scale-down is triggered. Prevents premature scale-down during brief lulls.
	IdleDuration time.Duration `yaml:"idle_duration"`
}

ScaleDownConfig holds scale-down thresholds.

type ScaleUpConfig

type ScaleUpConfig struct {
	// MemoryThreshold is the maximum memory-usage percentage (heap/sys*100) below
	// which scale-up is permitted. Protects against scaling under memory pressure.
	MemoryThreshold int `yaml:"memory_threshold"`
	// QueueDepthTrigger is the minimum queue depth that triggers a scale-up check.
	QueueDepthTrigger int `yaml:"queue_depth_trigger"`
	// AllWorkersBusy, when true, requires all workers to be active before scaling up.
	AllWorkersBusy bool `yaml:"all_workers_busy"`
}

ScaleUpConfig holds scale-up thresholds.

type ScalingControlReader

type ScalingControlReader interface {
	GetScalingControl(ctx context.Context) (*models.ScalingControl, error)
}

ScalingControlReader reads the current manual scaling override. store.Store satisfies this interface.

type ScalingEvent

type ScalingEvent = models.ScalingEvent

ScalingEvent is an alias for the shared models type. All code within this package uses models.ScalingEvent so callers share one type.

type SystemCollector

type SystemCollector interface {
	Collect() metrics.SystemSnapshot
}

SystemCollector provides runtime system snapshots. metrics.SystemCollector satisfies this interface.

type ThresholdPolicy

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

ThresholdPolicy is a Policy implementation driven by configurable thresholds. It is safe for concurrent use.

func NewThresholdPolicy

func NewThresholdPolicy(cfg PolicyConfig) *ThresholdPolicy

NewThresholdPolicy creates a ThresholdPolicy with the given configuration. Invalid values are silently clamped to safe defaults (min/max bounds).

func (*ThresholdPolicy) Evaluate

Evaluate returns the recommended scaling decision given current metrics. It considers queue depth, worker utilisation, memory pressure, idle duration, and the cooldown period.

func (*ThresholdPolicy) NotifyScaled

func (p *ThresholdPolicy) NotifyScaled()

NotifyScaled records the time of a scale event for cooldown tracking. The autoscaler calls this after it applies a decision.

Jump to

Keyboard shortcuts

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