Spot Schedules (pluggable providers)¶
A ScheduledMachine answers one question every reconcile: should this machine
exist right now? It answers it by referencing a spot-schedule provider via
the required spec.schedule — an
external resource that publishes the verdict. The default first-party provider is
TimeBasedSpotSchedule, which computes the
decision from a day / hour / timezone window. Other providers
(CapitalMarketsSchedule, third-party
ones) are referenced the same way — so activation can follow anything an operator
can model: an exchange calendar, a PromQL signal, a change-freeze window, or a
plain manual toggle.
This is the design recorded in ADR 0006.
Why a duck-typed provider, not more spec.schedule fields¶
Every new activation semantic could be a new field on spec.schedule. That path
never ends — 5-Spot would have to own every scheduling dialect (holiday lists,
half-days, PromQL, freeze calendars …) forever, and operators still couldn't
express anything 5-Spot didn't anticipate.
Instead 5-Spot defines where the decision lives — a boolean status.active
on a provider object — and lets the provider own how it's computed. 5-Spot
reads only that boolean (and a recommended Ready condition); it never reads the
provider's spec and never writes the provider object. This is exactly the
duck-typed contract Cluster API uses for infrastructureRef /
bootstrap.configRef, which 5-Spot already participates in from the other side.
New activation semantics therefore ship out of tree as a provider CRD +
controller, with no change to 5-Spot. The full provider contract is in the
Spot Schedule Provider Contract; the
CapitalMarketsSchedule provider is the
in-repo reference.
Referencing a provider¶
spec.schedule is a required object reference — apiVersion / kind / name
— to a provider object in the same namespace as the ScheduledMachine:
spec:
schedule:
apiVersion: spotschedules.5spot.finos.org/v1alpha1
kind: CapitalMarketsSchedule
name: nyse-equities
The group must be spotschedules.5spot.finos.org (enforced at the CRD
schema, the admission policy, and at runtime). Cross-namespace references are a
deliberate non-goal — a provider can only influence machines in its own
namespace.
The verdict, spec.enabled, and killSwitch¶
There is no composition — the single referenced provider's status.active is
the activation decision. spec.enabled (default true) is the administrative
master switch: setting it false holds the machine in the Disabled phase no
matter what the provider says. spec.killSwitch is a terminal teardown and
always wins. Precedence, highest first:
Event-driven, fail-safe¶
5-Spot watches referenced providers: a provider's status.active flip wakes
the referencing machines at watch latency, not on a polling timer (the dynamic
watch manager runs one watch stream per referenced provider kind). See
flow-spot-schedule-activation.
A provider that can't be resolved — its CRD isn't installed, the object is gone,
it exposes no status.active, or it reports Ready ≠ True — never flaps a
machine. 5-Spot holds the last known state (and fails inactive only if the
reference never resolved at all), surfacing a SpotScheduleResolved=False
condition and a fivespot_spot_schedule_resolution_errors_total metric instead.
A misbehaving provider's blast radius is exactly that of editing
spec.enabled — bounded to the same-namespace machines that named it
(see the threat model).
See also¶
- Spot Schedule Provider Contract — implement a provider
- CapitalMarketsSchedule provider guide — the reference provider
- ScheduledMachine — the consuming resource
- TimeBasedSpotSchedule provider — the default first-party provider
- Schedule Configuration — the day / hour window grammar
TimeBasedSpotScheduleuses