refactor(#2449): dashboard + docs for the SetWanted node
- builds.js NODE_KIND_LABEL: 'set wanted' (and the previously-missing 'noop') so the new head node renders with a label, not the raw kind. - docs/coordinator.md + templates.rs module doc: the power-op DAG shapes now show the head SetWanted node; SetWanted added to the lease-needing list with the atomicity rationale.
This commit is contained in:
parent
5fe8008cce
commit
9a39a54820
2 changed files with 22 additions and 11 deletions
|
|
@ -74,14 +74,19 @@ container build:
|
|||
|
||||
### Every operation as a DAG
|
||||
|
||||
The power ops write the durable `wanted` intent via a head `SetWanted`
|
||||
node (not a pre-submit side effect) — it holds the agent lease, so
|
||||
intent-write + reconcile is atomic per-agent.
|
||||
|
||||
```text
|
||||
rebuild(a): Prebuild(a) → StopForUpdate(a) → Swap(a) →(after-any) Reconcile(a)
|
||||
graceful-stop(a): [wanted=Offline] Signal(a) → Drain(a) → Reconcile(a)
|
||||
restart(a): [wanted=Up] StopForUpdate(a) → Reconcile(a)
|
||||
graceful-restart(a): [wanted=Up] Signal(a) → Drain(a) → StopForUpdate(a) → Reconcile(a)
|
||||
start(a): [wanted=Up] Reconcile(a) (stale rev ⇒ upgraded to rebuild)
|
||||
stop(a): [wanted=Offline] Reconcile(a)
|
||||
spawn(a): [wanted=Up] Create(a) → WriteDropin(a) → Reconcile(a)
|
||||
graceful-stop(a): SetWanted(a,Off) → Signal(a) → Drain(a) → Reconcile(a)
|
||||
restart(a): SetWanted(a,Up) → StopForUpdate(a) → Reconcile(a)
|
||||
graceful-restart(a): SetWanted(a,Up) → Signal(a) → Drain(a) → StopForUpdate(a) → Reconcile(a)
|
||||
start(a): SetWanted(a,Up) → Reconcile(a) (stale rev ⇒ stale-start below)
|
||||
stale-start(a): SetWanted(a,Up) → «rebuild subgraph» (prebuild noops — agent is down)
|
||||
stop(a): SetWanted(a,Off) → Reconcile(a)
|
||||
spawn(a): [wanted=Up at approve] Create(a) → WriteDropin(a) → Reconcile(a)
|
||||
perm-change(a): WritePermFile(a) → «rebuild subgraph»
|
||||
meta-update(inp): MetaLock(inp) → «fan-out rebuild(a) per affected agent»
|
||||
boot: (if any rev marker stale) MetaLock(hyperhive) → «fan-out rebuild»;
|
||||
|
|
@ -141,11 +146,15 @@ resources are free. Resources:
|
|||
held by nix-heavy nodes for the node's duration.
|
||||
2. **Per-agent lifecycle lease** — keyed on the **node's** agent (agent is
|
||||
per-node; a DAG can span agents) and globally exclusive per agent across
|
||||
all DAGs: acquired at a container-affecting node (`StopForUpdate`, `Swap`,
|
||||
`Signal`, `Drain`, `Reconcile`, `WriteDropin`, `Create`, `ApprovalDeploy`),
|
||||
held by the owning DAG until it's terminal, so two DAGs never interleave
|
||||
container ops on the same agent. A DAG touching several agents holds one
|
||||
lease per agent. **Lease-exempt**: `Prebuild`, `MetaLock`, `WritePermFile` —
|
||||
all DAGs: acquired at a container-affecting node (`SetWanted`,
|
||||
`StopForUpdate`, `Swap`, `Signal`, `Drain`, `Reconcile`, `WriteDropin`,
|
||||
`Create`, `ApprovalDeploy`), held by the owning DAG until it's terminal,
|
||||
so two DAGs never interleave container ops on the same agent. A DAG
|
||||
touching several agents holds one lease per agent. (`SetWanted` is a store
|
||||
write, not a container op, but takes the lease anyway so a power-op DAG's
|
||||
intent write + reconcile is atomic — two racing ops can't clobber intent
|
||||
before either reconciles.) **Lease-exempt**: `Prebuild`, `MetaLock`,
|
||||
`WritePermFile` —
|
||||
they touch the store / meta, not the running container, which is exactly
|
||||
why a stop can land while another DAG's prebuild is still building.
|
||||
|
||||
|
|
|
|||
|
|
@ -154,6 +154,8 @@ const NODE_KIND_LABEL = {
|
|||
write_dropin: 'dropin',
|
||||
write_perm_file: 'perm file',
|
||||
approval_deploy: 'deploy',
|
||||
set_wanted: 'set wanted',
|
||||
noop: 'noop',
|
||||
};
|
||||
|
||||
// The currently-running node of a DAG (per-node `step` labels + build
|
||||
|
|
|
|||
Loading…
Reference in a new issue