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.
41 lines
2.4 KiB
SQL
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;
|