Postgres storage. Safe to run on any number of nodes.
How a batch is delivered
BEGIN
SELECT pg_try_advisory_xact_lock(outbox_key, partition) -- or give up: another node has it
SELECT ... WHERE status = 'pending' ... ORDER BY id LIMIT batch_size
-- relay delivers the batch
DELETE ... -- or mark delivered / failed
COMMITThe advisory lock is scoped to the transaction, so it is released when the
transaction ends for any reason, including the worker or the node dying.
Nothing has to expire and no row is ever "claimed" with an UPDATE, which
is why a delivered message costs one INSERT and one DELETE.
Transaction-scoped locks also work behind PgBouncer in transaction mode.
Things to know
- The transaction stays open while the relay talks to the broker, so each
busy partition holds one connection from the repo pool. Size the pool
for
sum of partitionson top of your normal load, and keepbatch_sizeand relay timeouts modest. - The repo must use the default
READ COMMITTEDisolation level. - With
notify: true, publishing issuespg_notify, which Postgres delivers only if and when the publishing transaction commits.