-- Download lifecycle (M502 #5523), ported from Fabled Librarian's System 104: -- a download that stalls or fails is given up and its album searched again; -- an imported download seeds, then is removed. -- -- download_interventions what was seen wrong with a download or a client, -- what Minstrel did about it, and whether it -- cleared. One open row per (client, download, -- condition), updated in place. -- grabs (columns) a grab also ends by being given up (stalled, -- failed), set aside by a person, or leaving the -- client; an imported one records its seeding. -- release_blocks a release given up on is held back for a while, -- not for ever: expires_at. -- acquisition_settings how long to seed, and how long a download may sit -- with nobody sharing it. CREATE TABLE download_interventions ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), -- The acquisition_services code of the download client. client text NOT NULL, -- The torrent, or '' for a condition of the client itself. info_hash text NOT NULL DEFAULT '', grab_id uuid REFERENCES grabs (id) ON DELETE SET NULL, name text NOT NULL DEFAULT '', -- no_peers nobody is sharing an unfinished download. -- no_metadata still fetching the torrent's file list. -- client_error the client gave up on it, in its own words. -- client_unreachable the client does not answer, or its engine is down. -- gone the client no longer lists a running download. -- not_removed given up on, and the client would not remove it. trigger text NOT NULL CONSTRAINT download_interventions_trigger_check CHECK (trigger IN ( 'no_peers', 'no_metadata', 'client_error', 'client_unreachable', 'gone', 'not_removed')), -- escalated seen and shown; nothing done yet. -- retried asked the trackers again and re-read the files. -- given_up the download was removed and its album searched again. -- removed a download left behind was removed. action text NOT NULL DEFAULT 'escalated' CONSTRAINT download_interventions_action_check CHECK (action IN ('escalated', 'retried', 'given_up', 'removed')), outcome text NOT NULL DEFAULT 'open' CONSTRAINT download_interventions_outcome_check CHECK (outcome IN ('open', 'resolved')), detail text NOT NULL DEFAULT '', -- How many passes have seen it, and how many times Minstrel acted on it. -- The second is the retry ladder's rung, kept here so a restart does not -- hand a stuck download fresh retries. observations integer NOT NULL DEFAULT 1, remediations integer NOT NULL DEFAULT 0, first_seen timestamptz NOT NULL DEFAULT now(), last_seen timestamptz NOT NULL DEFAULT now(), settled_at timestamptz, CONSTRAINT download_interventions_settled_together CHECK ((outcome = 'open') = (settled_at IS NULL)) ); -- One open row per condition: a pass that sees it again lands on the same row. CREATE UNIQUE INDEX download_interventions_one_open ON download_interventions (client, info_hash, trigger) WHERE outcome = 'open'; CREATE INDEX download_interventions_grab_idx ON download_interventions (grab_id) WHERE grab_id IS NOT NULL; ALTER TABLE grabs DROP CONSTRAINT grabs_end_reason_check; ALTER TABLE grabs ADD CONSTRAINT grabs_end_reason_check CHECK (end_reason IN ('', 'superseded', 'imported', 'refused', 'held', 'stalled', 'failed', 'abandoned', 'gone')); -- An imported download goes on sharing (the files were copied) until its -- ratio reaches the setting or its time is up; seed_released_at is when it -- was removed, or found gone. ALTER TABLE grabs ADD COLUMN seeding boolean NOT NULL DEFAULT false, ADD COLUMN ratio real NOT NULL DEFAULT 0, ADD COLUMN seed_released_at timestamptz; CREATE INDEX grabs_seeding_idx ON grabs (imported_at) WHERE seeding AND seed_released_at IS NULL; -- stalled: given up on because it would not finish; held back until -- expires_at. NULL is for good. ALTER TABLE release_blocks DROP CONSTRAINT release_blocks_reason_check; ALTER TABLE release_blocks ADD CONSTRAINT release_blocks_reason_check CHECK (reason IN ('operator', 'files', 'import', 'stalled')); ALTER TABLE release_blocks ADD COLUMN expires_at timestamptz; -- FL's rulings: seed to ratio 2.0 or for 14 days at most; a download nobody -- has shared for 6 hours is retried, then given up. -- seed_ratio 0 the download is removed once imported. -- seed_days 0 no time limit: only the ratio ends it. -- stall_hours 0 never give up on a download for want of peers (a failed -- one is still given up). ALTER TABLE acquisition_settings ADD COLUMN seed_ratio real NOT NULL DEFAULT 2.0 CONSTRAINT acquisition_settings_seed_ratio_check CHECK (seed_ratio BETWEEN 0 AND 100), ADD COLUMN seed_days integer NOT NULL DEFAULT 14 CONSTRAINT acquisition_settings_seed_days_check CHECK (seed_days BETWEEN 0 AND 365), ADD COLUMN stall_hours integer NOT NULL DEFAULT 6 CONSTRAINT acquisition_settings_stall_hours_check CHECK (stall_hours BETWEEN 0 AND 720);