Documentation
¶
Overview ¶
Package depwait resolves a controller's NamedResource dependencies for the dag scheduler: Classify decides, WITHOUT blocking, whether each dep is Ready, terminally Failed, or still blocked (parkable). The shared readiness predicates (readyNow, depExists, the ReadyExpr evaluator, Existence-index promotion) live here so the gate semantics are single-sourced.
Index ¶
Constants ¶
const DefaultTimeout = 30 * time.Second
DefaultTimeout is the per-dep timeout when not specified. The upstream Flux controllers default to several minutes since they wait for in-cluster reconciliation; flate is purely offline, so waits past a few seconds almost always indicate a misconfigured reference. Keep this short so typos in dependsOn / sourceRef surface immediately instead of stalling a render.
Variables ¶
This section is empty.
Functions ¶
func TimeoutFromSpec ¶
TimeoutFromSpec resolves a Flux spec.timeout (`*metav1.Duration` — the shape used by both Kustomization and HelmRelease) into the effective per-dep wait. Honors a user-supplied value when set; falls back to flate's offline-tuned DefaultTimeout otherwise. Matches the principle that a real Flux reconcile would respect spec.timeout.
Types ¶
type ClassKind ¶ added in v0.3.4
type ClassKind int
ClassKind is the non-blocking resolution of one dependency for the dag engine.
const ( // ClassReady means the dependency is satisfied; the consumer may proceed. ClassReady ClassKind = iota // ClassFailed means the dependency is terminally unsatisfiable; Message // carries the canonical terminal reason for the failure. ClassFailed // ClassBlocked means the dependency is not yet satisfied but possibly // producible; the scheduler parks the consumer keyed on it. ClassBlocked )
type Classification ¶ added in v0.3.4
Classification is the result of Classify.
type ErrBlocked ¶ added in v0.3.4
type ErrBlocked struct {
Deps []manifest.NamedResource
}
ErrBlocked is the control-flow sentinel a dag-engine Require returns when a reconcile body cannot proceed because one or more dependencies are not yet satisfied — absent (not in the store), present-but-not-Ready, or carrying a ReadyExpr that has not yet evaluated true — AND none is terminally Failed. The scheduler parks the node keyed on Deps and re-runs the body when any of them advances; at the structural fixpoint a draining re-run terminalizes the node with the canonical failure status.
It deliberately has NO Unwrap and wraps no sentinel: it must never satisfy an errors.Is chain for a user-facing failure (manifest.ErrInput / ErrFlux / ErrObjectNotFound) or be mistaken for a reconcile error. RunWithStatusOutcome intercepts it via errors.As before the generic Failed-status write, so a blocked node keeps the Pending status its Require wrote and stays re-runnable.
Deps carries only the dependency identities, not a per-dep reason: the terminal failure message for a dependency that never becomes producible is re-derived structurally at the draining sweep (Classify re-reads the final store state) — so a stale park-time reason would be both redundant and, if the dep's state changed, wrong.
func (*ErrBlocked) Error ¶ added in v0.3.4
func (e *ErrBlocked) Error() string
type ExistenceLookup ¶
type ExistenceLookup interface {
// IsFileIndexed reports whether id has a file-existence record.
IsFileIndexed(id manifest.NamedResource) bool
// Promote attempts to materialize id into the Store from the
// file-existence index. Returns true when promotion succeeded
// and id is now reachable via store.GetObject.
Promote(id manifest.NamedResource) bool
}
ExistenceLookup is the seam Classify uses to resolve missing dependencies. Bundled into one interface so the orchestrator (and any future embedder) wires a single object through the controller Options pipe instead of two parallel closures.
The orchestrator's implementation reads from the loader's ExistenceIndex — file-indexed objects (CMs/Secrets/HRs the DiscoveryOnly loader kept out of the Store) get lazy-promoted the moment a depwait edge needs them, while render-only ids (no file record) stay absent until a parent render's emitRenderedChildren chain produces them.
type Summary ¶
type Summary struct {
Failed []manifest.NamedResource
Messages map[manifest.NamedResource]string
}
Summary tallies the failed dependencies of a Require gate. base.Require appends each terminally-failed dep and its reason; base.DepFailed folds the result into a manifest.DependencyFailedError.
type Waiter ¶
type Waiter struct {
Store *store.Store
Parent manifest.NamedResource
Timeout time.Duration
// AdditiveReadyExpr toggles Flux's AdditiveCELDependencyCheck
// feature gate. When false (the default, matching Flux), a
// dep's ReadyExpr REPLACES the built-in Ready check — flate
// treats the dep as Ready when the expression returns true. When
// true, the dep must satisfy both the built-in Ready check AND
// the ReadyExpr (additive mode).
AdditiveReadyExpr bool
// Existence, when non-nil, lets Classify lazy-promote a missing dep
// from the loader's file-existence index before deciding it is
// absent. The orchestrator wires this against the ExistenceIndex;
// tests supply stubs. When nil, an absent dep is simply absent.
//
// See ExistenceLookup for the decision matrix.
Existence ExistenceLookup
}
Waiter holds the parameters for one dependency-classification operation.
func (*Waiter) Classify ¶ added in v0.3.4
func (w *Waiter) Classify(dep manifest.DependencyRef, drainLevel int) Classification
Classify resolves dep for the dag engine WITHOUT blocking, reusing the shared readiness predicates (readyNow, depExists, the ReadyExpr evaluator, Existence.Promote). drainLevel escalates how an unsatisfied dependency is treated at the structural fixpoint and selects the canonical terminal message: notFound ("dependency not found"), the raw stored Failed message, "not ready" (a present-Pending dep at the force level), and the readyExpr strings.
MUST run on a worker goroutine (it reads the store) — never under the scheduler's mutex.