-- broker_get function -- Fetches the next job from the queue for a given queue number -- Returns: p_retval (0=success, >0=error), p_errmsg (error message), p_job_id (job ID if found) CREATE OR REPLACE FUNCTION broker_get( p_queue_number INTEGER, p_instance_id BIGINT DEFAULT NULL, OUT p_retval INTEGER, OUT p_errmsg TEXT, OUT p_job_id BIGINT ) RETURNS RECORD LANGUAGE plpgsql AS $$ DECLARE v_job_record RECORD; BEGIN p_retval := 0; p_errmsg := ''; p_job_id := NULL; -- Validate queue number IF p_queue_number IS NULL OR p_queue_number <= 0 THEN p_retval := 1; p_errmsg := 'Invalid queue number'; RETURN; END IF; -- Find and lock the next pending job for this queue -- Uses SKIP LOCKED to avoid blocking on jobs being processed by other workers -- Skip jobs with pending dependencies SELECT id_broker_jobs, job_name, job_priority, execute_str INTO v_job_record FROM broker_jobs WHERE job_queue = p_queue_number AND complete_status = 0 -- pending AND ( depends_on IS NULL -- no dependencies OR depends_on = '{}' -- empty dependencies OR NOT EXISTS ( -- all dependencies completed SELECT 1 FROM broker_jobs dep WHERE dep.job_name = ANY(broker_jobs.depends_on) AND dep.complete_status = 0 -- pending dependency ) ) ORDER BY job_priority DESC, created_at ASC LIMIT 1 FOR UPDATE SKIP LOCKED; -- If no job found, return success with NULL job_id IF NOT FOUND THEN RETURN; END IF; -- Update job status to running UPDATE broker_jobs SET complete_status = 1, -- running started_at = NOW(), rid_broker_queueinstance = p_instance_id, updated_at = NOW() WHERE id_broker_jobs = v_job_record.id_broker_jobs; -- Return the job ID p_job_id := v_job_record.id_broker_jobs; EXCEPTION WHEN OTHERS THEN p_retval := 2; p_errmsg := SQLERRM; RAISE WARNING 'broker_get error: %', SQLERRM; END; $$; -- Comments COMMENT ON FUNCTION broker_get IS 'Fetches the next pending job from the specified queue';