Description
Postgres advisory locks are used to ensure only a single subscription process can subscribe to each uniquely named EventStore subscription. This ensures events are only processed by a single susbcription, regardless of how many nodes are running in a multi-node deployment.
One consequence of this design is that when multiple nodes are started it will likely be the first node which starts that acquires locks for all the started subscriptions This means that load won't be evenly distributed amongst the available nodes in the cluster. You could use distributed Erlang to evenly distribute subscriber processes amongst the available nodes in the cluster.
For scenarios where distributed Erlang is not used, to help balance load more evently the subscription lock could be released after a configurable interval (e.g. hourly with random jitter). This would allow a subscription process running on another to connect and resume processing. It may be necessary to broadcast a "lock released" message to connected nodes, triggering lock acquisition on another node, to reduce latency. Eventually subscription processes should be randomly distributed amongst all running nodes in the cluster.
The pg_locks
table can be used to identify locks acquired on the EventStore subscriptions
table from any connected node:
SELECT * FROM pg_locks
WHERE classid = 'public.subscriptions'::regclass
AND locktype = 'advisory';
This could be used to determine if locks are fairly distributed or not by grouping and counting by PID:
SELECT pid, COUNT(*)
FROM pg_locks
WHERE classid = 'subscriptions'::regclass
AND locktype = 'advisory'
GROUP BY pid;