Skip to content

Add optional time-to-live to subscription lock #213

Open
@slashdotdash

Description

@slashdotdash

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;

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions