From bb3875719c61bd101e67dc0324f1ec63225a6b0c Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Thu, 11 Jun 2026 06:41:33 -0500 Subject: [PATCH] feat(database): claim_songstats_backfill_rows RPC (FOR UPDATE SKIP LOCKED) Atomic batch claim for the backfill worker: pending rows in rank_score DESC order, marked in_progress and returned in one statement; concurrent workers skip locked rows. SECURITY INVOKER + policy-less RLS keeps it service-role only. Part of recoupable/chat#1791 (write path). Co-Authored-By: Claude Fable 5 --- ...11000000_claim_songstats_backfill_rows.sql | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 supabase/migrations/20260611000000_claim_songstats_backfill_rows.sql diff --git a/supabase/migrations/20260611000000_claim_songstats_backfill_rows.sql b/supabase/migrations/20260611000000_claim_songstats_backfill_rows.sql new file mode 100644 index 0000000..bfacdb8 --- /dev/null +++ b/supabase/migrations/20260611000000_claim_songstats_backfill_rows.sql @@ -0,0 +1,25 @@ +-- Atomic claim function for the Songstats backfill worker (recoupable/chat#1791). +-- FOR UPDATE SKIP LOCKED can't be expressed through supabase-js, so the worker +-- claims its batch via this RPC: pending rows in value order (rank_score DESC), +-- marked in_progress and returned in one statement. Concurrent workers skip +-- each other's locked rows instead of blocking. +-- +-- SECURITY INVOKER (default): RLS on songstats_backfill_queue has no policies, +-- so only the service-role worker (which bypasses RLS) can claim rows; anon / +-- authenticated callers get zero rows even if they can execute the function. + +CREATE OR REPLACE FUNCTION claim_songstats_backfill_rows(batch_size integer) +RETURNS SETOF songstats_backfill_queue +LANGUAGE sql +AS $$ + UPDATE songstats_backfill_queue q + SET status = 'in_progress', updated_at = now() + WHERE q.id IN ( + SELECT id FROM songstats_backfill_queue + WHERE status = 'pending' + ORDER BY rank_score DESC + FOR UPDATE SKIP LOCKED + LIMIT batch_size + ) + RETURNING q.*; +$$;