PostgreSQL advisory lock-based leader election with notification channels.
Ensures only one instance in a cluster acts as the leader, using PostgreSQL advisory locks for distributed coordination and LISTEN/NOTIFY for real-time event routing.
npm install @platformatic/leader'use strict'
const pg = require('pg')
const createLeaderElector = require('@platformatic/leader')
const pool = new pg.Pool({
connectionString: 'postgres://localhost/mydb'
})
const leader = createLeaderElector({
pool,
lock: 4242,
poll: 10000,
channels: [
{
channel: 'my_events',
onNotification: (payload) => {
console.log('Received:', payload)
}
}
],
onLeadershipChange: (isLeader) => {
console.log('Leadership changed:', isLeader)
}
})
leader.start()
// Send a notification to the leader
await leader.notify({ action: 'refresh' }, 'my_events')
// Check if this instance is the leader
console.log(leader.isLeader())
// Stop the leader elector
await leader.stop()
await pool.end()Returns an object with { start, stop, notify, isLeader }.
| Option | Type | Required | Default | Description |
|---|---|---|---|---|
pool |
pg.Pool |
Yes | - | A node-postgres pool instance |
lock |
number |
Yes | - | PostgreSQL advisory lock ID |
poll |
number |
No | 10000 |
Polling interval in milliseconds |
channels |
Array |
Yes | - | Notification channel configurations |
log |
object |
No | pino() |
Logger with info, debug, warn, error methods |
onLeadershipChange |
function |
No | null |
Callback invoked with (isLeader: boolean) when leadership status changes |
Each channel in the channels array must have:
channel(string) - PostgreSQL notification channel nameonNotification(function) - Handler called with the parsed payload when a notification arrives
start()- Begins the leader election loop. Returns a promise.stop()- Stops the leader election loop and releases resources.notify(payload, channelName)- Sends a notification on the given channel. The payload is JSON-serialized.isLeader()- Returnstrueif this instance is currently the leader.
- Each instance periodically attempts to acquire a PostgreSQL advisory lock using
pg_try_advisory_lock. - The instance that acquires the lock becomes the leader and starts listening for notifications via
LISTEN. - Only the leader processes incoming notifications and routes them to the appropriate channel handler.
- If the leader stops or loses the lock, another instance acquires it and takes over.
- The
onLeadershipChangecallback fires whenever the leadership status transitions.
Start PostgreSQL:
docker compose up -d
Run tests:
node --test test/*.test.js
Apache-2.0