mirror of
https://github.com/block/buzz.git
synced 2026-10-27 20:41:57 +00:00
42 lines
1.9 KiB
PL/PgSQL
42 lines
1.9 KiB
PL/PgSQL
-- Channel TTL refresh (keep in sync with migrations/0024). Runs deferred, in
|
|
-- the transaction that makes a channel-scoped event durable, so a TTL
|
|
-- transition committed while ingest was in flight is never missed. The
|
|
-- per-channel advisory lock is SHARED here — permanent-channel commits admit
|
|
-- each other — and taken EXCLUSIVE by TTL transitions (update_channel in
|
|
-- crates/buzz-db/src/channel.rs), which forces the same total order the
|
|
-- 0022 row lock provided without serializing the hot path.
|
|
CREATE FUNCTION refresh_channel_ttl_after_event_insert() RETURNS trigger
|
|
LANGUAGE plpgsql AS $$
|
|
DECLARE
|
|
channel_ttl INTEGER;
|
|
BEGIN
|
|
-- Kind 9007 creates the channel and initializes its deadline itself.
|
|
IF NEW.channel_id IS NOT NULL AND NEW.kind <> 9007 THEN
|
|
BEGIN
|
|
PERFORM pg_advisory_xact_lock_shared(hashtextextended(
|
|
'buzz_channel_ttl:' || NEW.community_id::text || ':' || NEW.channel_id::text, 0));
|
|
|
|
SELECT ttl_seconds INTO channel_ttl
|
|
FROM channels
|
|
WHERE community_id = NEW.community_id AND id = NEW.channel_id;
|
|
|
|
IF channel_ttl IS NOT NULL THEN
|
|
UPDATE channels
|
|
SET ttl_deadline = clock_timestamp() + make_interval(secs => ttl_seconds)
|
|
WHERE community_id = NEW.community_id
|
|
AND id = NEW.channel_id
|
|
AND ttl_seconds IS NOT NULL
|
|
AND archived_at IS NULL
|
|
AND deleted_at IS NULL;
|
|
END IF;
|
|
EXCEPTION WHEN OTHERS THEN
|
|
-- Preserve the existing best-effort contract: a TTL refresh failure
|
|
-- must not reject an otherwise valid durable event.
|
|
RAISE WARNING 'channel TTL refresh failed for community %, channel %: %',
|
|
NEW.community_id, NEW.channel_id, SQLERRM;
|
|
END;
|
|
END IF;
|
|
RETURN NULL;
|
|
END
|
|
$$;
|