Class: PostgresMutexDriver
The PostgreSQL driver ({type: 'postgres'}): the locks are shared by every instance connected to the same database with the same prefix. It needs the optional peer dependency pg (8); without it, the first acquisition fails with MutexDriverNotFoundException. It has two modes:
'advisory'(the default): session advisory locks (pg_try_advisory_lock) taken on one connection of the driver, opened at the first use. They do not expire and need no renewal: PostgreSQL releases them when the connection closes, so a crashed process frees them at once. When the connection closes or fails, every lock it held is lost (a Mutex aborts their signals) and the next acquisition opens a new connection. A connection cut without the client noticing it is not detected by the renewals. No fencing token. The lock names are hashed to 64-bit keys, shared with the other advisory locks of the database. It does not work through a pooler in transaction mode (PgBouncer), which does not keep the session.'table': one row per lock in a table, created at the first use with its sequence<table>_fence. The rows expire by the database clock after theirttlunless renewed, so it works through the poolers and on the replicated setups writing to one primary, and each acquisition gets a fencing token from the sequence. A pool of 4 connections is used.
Example
import {PostgresMutexDriver, type DriverLock} from 'lakutata/com/mutex'
const driver: PostgresMutexDriver = new PostgresMutexDriver({
host: '127.0.0.1',
database: 'app',
username: 'app',
password: 'secret'
}, 'my-app:', 'table', 'app_locks')
const lock: DriverLock | undefined = await driver.acquire('invoice:7', 30000)
if (lock) await driver.release('invoice:7', lock)
await driver.close()Extends
Constructors
Constructor
new PostgresMutexDriver(
connection,prefix,mode?,table?):PostgresMutexDriver
Create a driver on a PostgreSQL database; it connects at its first use.
Parameters
connection
The connection to the database.
prefix
string
The prefix added to the lock names.
mode?
"advisory" | "table"
'advisory' (the default) or 'table'.
table?
string
The table of the table mode, optionally qualified by its schema (locks.mutex); 'lakutata_mutex' by default.
Returns
PostgresMutexDriver
Throws
When the table is not a valid PostgreSQL name (letters, digits and _, not starting with a digit).
Overrides
Properties
expiring
readonlyexpiring:boolean
true in the table mode (the rows expire), false in the advisory mode (the locks end with the connection).
Overrides
onLost
onLost: (
names) =>void
Called with the names of the locks the driver lost at once, when the connection holding advisory locks closes or fails. A Mutex sets it; it does nothing by default.
Parameters
names
string[]
Returns
void
Inherited from
Methods
acquire()
acquire(
name,ttl):Promise<DriverLock|undefined>
Try to acquire a lock once: an advisory lock of the driver's connection, or a row inserted (or taken over when expired) in the table.
Parameters
name
string
The lock name.
ttl
number
How long the lock stays held without a renewal, in milliseconds (the table mode only).
Returns
Promise<DriverLock | undefined>
The lock (with a fencing token in the table mode), or undefined when another holder has it, this driver included.
Throws
When the package pg is not installed.
Overrides
close()
close():
Promise<void>
Close the connection (PostgreSQL releases its advisory locks) and the pool; the rows of the table mode stay until they expire.
Returns
Promise<void>
Overrides
extend()
extend(
name,lock,ttl):Promise<boolean>
Renew a lock: in the table mode, push back the expiration of its row when it still holds this holder's token; in the advisory mode, check that the driver still holds it on its connection, by a query (a connection cut without notice fails it).
Parameters
name
string
The lock name.
lock
The lock acquired.
ttl
number
How long the lock stays held without another renewal, in milliseconds (the table mode only).
Returns
Promise<boolean>
Whether the lock is still held by this holder.
Overrides
release()
release(
name,lock):Promise<boolean>
Release a lock still held by this holder: unlock the advisory lock, or delete the row.
Parameters
name
string
The lock name.
lock
The lock acquired.
Returns
Promise<boolean>
Whether it was released (false when the row expired and was taken, or the connection was lost).