feat(broker): migrations-based install, roles, RLS, and job dependency groups
Replace the ad-hoc tables/procedures install layout with versioned, ordered SQL migrations tracked in broker_schema_migrations. Add optional least-privilege role provisioning (--with-roles), multi-tenant row-level security, lease-based job claiming with stale-lease recovery, and job dependencies -- both by job id and by fan-in job group. Add Docker/Compose support for running the broker and its test suite.
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
-- 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)';
|
||||
Reference in New Issue
Block a user