Parallel Dispatch (pg_relay)¶
Optional parallel execution of a suite's checks through the pg_relay extension's queue and workers — see Parallel Execution via pg_relay in the User Guide for the narrative. The feature is spread across functions documented in their own chapters — p_use_pg_relay on pghf.create_check_run(), the enqueue behaviour of pghf.execute_check_run(), and the completion handling in pghf.evaluate_run() / pghf.run_and_evaluate() — leaving one function that lives here: the worker-side executor.
One-time setup (an operator with pg_relay management rights), registering the fixed channel the collection engine enqueues on:
SELECT pgrelay.register(
p_channel => 'pghf_check',
p_action => 'CALL pghf.execute_relay_check($1)',
p_notes => 'pg_health_framework parallel check execution',
p_action_type => 'sql',
p_concurrency_mode => 'channel_payload');
'channel_payload' (pg_relay 1.1+) lets different checks run in parallel while serialising duplicate events for the same check of the same run — extra insurance on top of pghf.execute_relay_check()'s own duplicate guard. On pg_relay 1.0, register without that parameter.
pghf.execute_relay_check(p_payload text)¶
The worker-side executor — the action behind pg_relay channel pghf_check, invoked by a pg_relay worker once per enqueued check. Performs, for that one check, the identical invoke / "value"-key contract check / error-capture / result-logging sequence the collection engine's sequential path performs. Not normally called by hand — but it's an ordinary procedure, and calling it directly with a well-formed payload is harmless (and is exactly how the test suite exercises it without pg_relay).
| Parameter | Type | Mandatory | Default | Description |
|---|---|---|---|---|
p_payload |
text |
Yes | — | The event payload the collection engine enqueued: {"run_id": "<uuid>", "check_uid": "<uuid>", "critical_only": false}. critical_only mirrors the enqueuing run's p_critical_only and is optional, defaulting false if absent. Raises on anything malformed, naming the payload. The run and check must both exist. |
Returns: nothing. This is a procedure, and it deliberately never commits — it runs inside pg_relay's own worker transaction, so a failure rolls back atomically and lands in pg_relay's log as the audit record.
Behaviour worth knowing:
- Idempotent per (run, check) — a duplicate delivery (a manual re-notify, a replayed event) finds the result row already present and silently does nothing, keeping evaluation's one-row-per-check assumption true.
- Re-checks blackout windows at execution time — the collection engine already gates on blackouts at submission, but a window that opens between enqueue and worker dispatch still suppresses: the worker logs the standard
SKIPPEDrow with the[blackout <id>]note instead of running the check. - Re-checks
p_critical_onlyat execution time, the same way — a check enqueued whilecritical_onlywas true and it was'critical'can, in principle, be confirmed back to non-critical by another run before a worker ever picks up the pending event; this re-check catches that and skips instead of running a now-stale critical-only request. See Scheduling Health Checks for why you'd use this at all. - Stamps the run's finish time — whichever worker logs the run's final expected result also sets
finished_at, serialised via a row lock so concurrent finishers can't miss each other. This is whatpghf.get_run_status()'sis_collection_completereflects, and whatpghf.evaluate_run()gates on. - Runs as the worker's own role — deliberately not
SECURITY DEFINER(the same dynamic-dispatch reasoning as the collection engine; see The Access Model). The pg_relay worker role therefore needs operator-grade access:INSERTonpghf.raw_resultsandUPDATEonpghf.runs(open by default), explicitSELECTonpghf.runs/pghf.raw_results/pghf.run_config(not open by default), and whatever the check bodies themselves read (pg_monitorcovers the built-ins). - Pins
search_pathtopg_catalog, public— pg_relay's dispatcher runs actions under its own internal path, which check bodies would otherwise inherit. Built-in checks are unaffected; a custom check reading objects in any other schema must schema-qualify them.
Continue to the Evaluation Engine.