Files
mesh-controller/internal/inventory/migrations/0105-the-chain-leaves-the-store.sql
T

53 lines
3.0 KiB
SQL

-- The tables of builds, rollouts and assignments leave the store (novox/hq ADR 0408 §8, design 47 milestone 5, issue 1096).
--
-- Delivery 1 wrote their rows into the bus's buckets at the controller's start and recorded each kind it had counted in
-- chain_moved; from then on nothing in the controller reads or writes the tables. This drops them. **It is one-way**: a
-- controller older than this schema is refused by the put-back gate, and the rows are in the buckets only.
--
-- **The guard comes first, in the same transaction as the drops**, because a migration runs when the store is opened, before
-- the controller of this delivery serves and before any connection to the bus: it can prove the move from the store alone.
-- A kind that holds rows and is not named in chain_moved was never moved, so dropping its tables would lose it; a pending
-- assignment still waiting, being made, or ended unmade with its condition unanswered has no mover (it is a value of the
-- assignments bucket from this delivery on), so the table must hold none. A store that never held a row of a kind — a new
-- mesh — passes. A migration that raises leaves nothing applied, `prepare` fails with the reason, and the running controller
-- keeps its tables.
do $$
declare
kind text;
holds boolean;
missing text[] := '{}';
begin
foreach kind in array array['builds', 'rollouts', 'assignments'] loop
holds := case kind
when 'builds' then exists (select 1 from build) or exists (select 1 from build_request)
when 'rollouts' then exists (select 1 from release_plan) or exists (select 1 from batched_merge)
when 'assignments' then exists (select 1 from assignment)
end;
if holds and not coalesce((select counts ? kind from chain_moved), false) then
missing := missing || kind;
end if;
end loop;
if array_length(missing, 1) > 0 then
raise exception 'the controller''s store still holds rows of % that chain_moved does not name as moved to the bus; '
'run the controller of the previous delivery and read chain_moved back first', array_to_string(missing, ', ');
end if;
if exists (select 1 from pending_assignment
where state in ('waiting', 'applying') or (raised_at is not null and acknowledged_at is null and cleared_at is null)) then
raise exception 'a pending assignment is still in the table (waiting, being made, or ended with its condition '
'unanswered); let it settle, then deliver again';
end if;
end
$$;
drop table build_request;
drop table build;
drop table batched_merge;
drop table release_plan;
drop table pending_assignment;
-- Its triggers go with it; the function they called goes here. The counter table stays: the controller raises it.
drop table assignment;
drop function raise_assignment_generation();
alter table node drop column sent_builds;
-- No reader of it remains. build_gate stays (issue 1097).
drop table chain_moved;