import db from '@adonisjs/lucid/services/db' /** Releases unchanged for this long are settled (ranges are read in order; the merger adds within minutes). */ const QUIET_HOURS = 6 /** * History: a release whose last post is QUIET_HOURS old gets nothing new from the tail, only from the * neighbouring ranges' fragments, which the merger adds within minutes: settled once unchanged this long. * Waiting QUIET_HOURS after it was read held every history release back from phase 2 for six hours after * each reset (the hourly sweeps' resets kept the prober idle; LOG.md 2026-10-12 (13)). */ const QUIET_HISTORY_MINUTES = 30 const BATCH = 50_000 /** * Settles releases (REBUILD.md, part 8): once nothing has been added for * QUIET_HOURS (QUIET_HISTORY_MINUTES once its last post is that old), its completeness is decided: complete when every file the * [i/N] counter announced was found, unknown without a counter (phase 2 * reads par2 sets for those). Phase 2 picks its work from settled releases. */ class Settler { async run(): Promise { let settled = 0 while (true) { // Their probe candidates become claimable (Prober.claim), the unreadable ones first. const { rows } = await db.rawQuery( `WITH settled AS ( UPDATE releases SET settled_at = now(), complete = CASE WHEN file_total IS NULL THEN NULL ELSE files >= file_total END WHERE id IN (SELECT id FROM releases WHERE settled_at IS NULL AND last_seen_at < now() - make_interval(mins => ?) AND (last_seen_at < now() - make_interval(hours => ?) OR coalesce(last_posted_at, posted_at) < now() - make_interval(hours => ?)) LIMIT ?) RETURNING id, readable, files, bytes, poster), marked AS (UPDATE probe_candidates pc SET ready = true, unreadable = NOT s.readable FROM settled s WHERE pc.release_id = s.id), -- Small ones may be an upload's .nfo or .nzb that came apart from it: the merger's sidecar fold looks at them. queued AS (INSERT INTO fold_candidates (release_id) SELECT id FROM settled WHERE files <= 3 AND bytes < 1000000 AND poster IS NOT NULL ON CONFLICT DO NOTHING) SELECT count(*)::int AS n FROM settled`, [QUIET_HISTORY_MINUTES, QUIET_HOURS, QUIET_HOURS, BATCH] ) const n = rows[0].n settled += n if (n < BATCH) return settled } } } export default new Settler()