Files
mesh-controller/internal/inventory/migrations/0068-order-and-one-writer.sql
T
jochen 2eb9a22c24 Act under a lease, keep accounts by order, one writer at composition (hq to-be 45 Phase 2)
Two controllers could both act (issue 204), a reconcile's report could
overtake the apply after it and the digest decided (issue 267), and a grant
could make a second writer of a machine's report.

- The lease (internal/lease, ADR 0229): mesh-controller_lease key `holder`,
  15 s age, renewed every 5 s by compare-and-set; the epoch is the revision
  it was taken at. The gate is the clock (stops 3 s before expiry); a refused
  renewal is a loss and the process exits; a holder that stops gives it back.
  serve takes it before asserting the bus. Epochs kept in the store
  (migration 0068 controller_epoch) as a floor: a bucket raised from nothing
  is compacted past it. Unleased (no epoch, S12 urgent) only when nobody
  holds it and the bus will not let it be written. A shell command acts
  under the holder's epoch, or its own lease when none.
- Declarations carry `epoch` inside the signed envelope, only to a machine
  whose latest account carried a report_sequence (mesh-host #35); would-send
  is composed with the epoch last sent. Allot and the send both pass the gate.
- Reports: contract in internal/link/order.go (epoch, sequence,
  report_sequence, older_than, refused_older). Accounts kept by epoch, then
  sequence, then report sequence; older refused, counted; unordered reports
  keep the digest rule. Plans by compare-and-set on a revision, with epoch.
  Conditions and calls carry the epoch and are not written off the lease.
- S12 and S13 (naming the writer by epoch) watched, D5 run; reset of the
  bucket said. Writers table compiled in and enforced in PermissionsFor; the
  controller no longer publishes mesh.control.>. A contract per consumed
  kind, and the empty-on-error lint over the repository.
- mesh-host pinned to its main with the epoch in the validator (D1 validates
  the envelope as sent).

Needs mesh-host's genesis lock with the lease grant (mesh-host PR) for
TestTheInstallersFirstUserListIsWhatTheControllerWouldCompose.
2026-10-06 12:29:18 +02:00

41 lines
2.4 KiB
SQL

-- Order and one writer (novox/hq to-be 45 §6, Phase 2).
--
-- The controller acts only while it holds its lease, and every act carries the lease's epoch: a
-- declaration, a plan write. A report carries the order of the declaration it accounts for, and the
-- controller keeps the highest per machine, refusing an older account rather than letting the last
-- one written win (issue 267). These are the records each of those needs.
-- Every epoch the mesh issued: which controller instance held it, from when, and how it ended —
-- given back, or lost (its key expired, or a renewal was refused). The highest one is the floor no
-- new epoch may be at or under, even when the lease's bucket was raised again from nothing; and a
-- stale refusal names its writer from here.
create table controller_epoch (
epoch bigint primary key,
instance text not null,
host text not null default '',
build text not null default '',
taken timestamptz not null default now(),
ended timestamptz,
-- how: 'released' (given back), 'lost' (its own renewal was refused or failed), 'expired'
-- (found expired by the next holder: it stopped renewing without saying so).
how text not null default ''
);
-- The epoch a machine was last sent, so what the mesh WOULD send is composed with it and reads as
-- byte for byte what it DID send when nothing else changed — a new holder's epoch is not a change
-- of the machine. Null for a declaration sent without one.
alter table node add column sent_epoch bigint;
-- Whether the machine's node-engine said it reads an epoch in a declaration (its report's `reads`):
-- until it has, it is sent none, because an older node-engine refuses a key it does not know, whole.
alter table node add column reads_epoch boolean not null default false;
-- The order of the account kept for each machine: the declaration's sequence and epoch it is about
-- and the node-engine's own report sequence. Null where the kept account carried none.
alter table node_report add column reported_sequence bigint;
alter table node_report add column reported_epoch bigint;
alter table node_report add column report_sequence bigint;
-- A plan is written by compare-and-set on its revision, and says the epoch that wrote it last.
alter table release_plan add column revision bigint not null default 0;
alter table release_plan add column epoch bigint;