Delivery 1 wrote no commit on the key of a pulled-in module, so after the upgrade those modules fell out of SentBuilds. At the start of the lease holder a copy fills every key that names no commit (creating a standing pulled-in key where none stands), overwrites nothing, empties each column it copied, and raises an urgent condition while it fails. Migration 0105 no longer drops node.sent_builds (issue 1112 does).
53 lines
3.0 KiB
SQL
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();
|
|
-- node.sent_builds STAYS, only as the source of the one-time copy onto the assignments' keys (issue 1109); dropping it is
|
|
-- issue 1112. build_gate stays (issue 1097).
|
|
drop table chain_moved;
|