-- broker.broker_register_instance -- Registers a broker instance, using a session-scoped advisory lock keyed by -- name to guarantee only one active instance per name -- no race window, no -- "check COUNT(*) then insert" gap. The caller MUST run this on a pinned -- connection it keeps open for the process lifetime (Go: db.Conn(ctx)) and -- release the lock (pg_advisory_unlock) itself on shutdown, since the lock -- lives with the backend session, not with the row. CREATE OR REPLACE FUNCTION broker.broker_register_instance( p_name TEXT, p_hostname TEXT, p_pid INTEGER, p_version TEXT, p_queue_count INTEGER, OUT p_retval INTEGER, OUT p_errmsg TEXT, OUT p_instance_id BIGINT ) RETURNS RECORD LANGUAGE plpgsql AS $$ DECLARE v_lock_key BIGINT; BEGIN p_retval := 0; p_errmsg := ''; p_instance_id := NULL; IF p_name IS NULL OR p_name = '' THEN p_retval := 1; p_errmsg := 'Instance name is required'; RETURN; END IF; IF p_hostname IS NULL OR p_hostname = '' THEN p_retval := 2; p_errmsg := 'Hostname is required'; RETURN; END IF; v_lock_key := hashtextextended('broker:' || p_name, 0); IF NOT pg_try_advisory_lock(v_lock_key) THEN p_retval := 3; p_errmsg := 'Another broker instance is already active for this name (advisory lock held). Only one broker instance per name is allowed.'; RETURN; END IF; INSERT INTO broker.broker_queueinstance ( name, hostname, pid, version, status, queue_count, started_at, last_ping_at ) VALUES ( p_name, p_hostname, p_pid, p_version, 'active', p_queue_count, NOW(), NOW() ) RETURNING id_broker_queueinstance INTO p_instance_id; EXCEPTION WHEN OTHERS THEN p_retval := 99; p_errmsg := SQLERRM; RAISE WARNING 'broker_register_instance error: %', SQLERRM; END; $$; COMMENT ON FUNCTION broker.broker_register_instance IS 'Registers a broker instance; caller must hold the connection open for the process lifetime (advisory lock is session-scoped)';