Distributed Locks
Coordinate processes across your cluster using TopGun’s distributed locking mechanism with built-in fencing tokens.
In a distributed system, you often need to ensure that only one client or process performs a specific action at a time (e.g., processing a payment, updating a shared resource). TopGun provides a simple API to acquire and release locks, backed by the server cluster.
Using Locks
client.getLock(name) to create a lock handle, then call lock(ttl) to attempt to acquire it.The ttl (Time-To-Live) ensures the lock is automatically released if the client crashes.
import { TopGunClient } from '@topgunbuild/client';
// ... initialize client ...
async function processJob() {
const lock = client.getLock('process-queue-1');
// Acquire lock with 5 second TTL (auto-release if client crashes)
const acquired = await lock.lock(5000);
if (acquired) {
try {
console.log('Lock acquired, processing job...');
// Perform critical section work here
await doHeavyWork();
} finally {
// Always release the lock when done
await lock.unlock();
console.log('Lock released');
}
} else {
console.log('Could not acquire lock, another worker is busy.');
}
} Fencing Tokens
When a lock is granted, the server returns a monotonically increasing number (the token).
Although the high-level lock() API handles this internally for release operations, you should ideally pass this token to any external storage systems you are modifying to verify that you still hold the valid lock.
Why is this needed?
If a client pauses (e.g., due to a long GC pause) and its lock expires, another client might acquire the lock. When the first client wakes up, it might try to write data, unaware it lost the lock. Fencing tokens allow the storage layer to reject the write from the old client (because its token is smaller than the current one).