IMQLock class
In-process, promise-based locks used to collapse concurrent identical calls: the first caller executes the work while later callers for the same key wait and are then resolved with the first caller's result.
Signature:
export declare class IMQLock
Remarks
These are not distributed locks. The lock table is a set of plain static objects held in memory, and nothing here touches Redis, the network or any shared store. Separate processes, cluster workers and service replicas each maintain their own independent locks and will run the guarded code concurrently. lock() inherits the same limitation. Use a Redis- or database-backed lock if you need mutual exclusion across processes.
Keys are used verbatim, with no prefixing or namespacing, so they are global to the process and unrelated call sites sharing a string share a lock.
Exclusion is not absolute, and IMQLock.deadlockTimeout is why. A waiter that times out frees the key so that a holder which never releases cannot poison it for the life of the process — but the holder is still running, so the next call acquires and runs alongside it. Pass the IMQLock.token() to IMQLock.release(), as the example does and as lock() does for you, and the damage stops there: the overtaken holder can no longer resolve the new holder's waiters or free a lock still in use. Set deadlockTimeout to 0 if you would rather have strict exclusion and let waiters wait forever.
Example
import { IMQLock, type AcquiredLock } from '@imqueue/rpc';
async function doSomething(): Promise<number | AcquiredLock<number>> {
const lock: AcquiredLock<number> =
await IMQLock.acquire<number>('doSomething');
// locked() is the only reliable way to tell holder from waiter
if (IMQLock.locked('doSomething')) {
// read the token straight after acquiring and pass it to every
// release, so a release cannot land on a later holder's lock
const token = IMQLock.token('doSomething');
// always wrap locked work in try/catch and release on both paths,
// otherwise waiters hang until the deadlock timeout fires
try {
// runs only once across all concurrent calls; every waiter
// resolves with this same value
const res = Math.random();
IMQLock.release('doSomething', res, undefined, token);
return res;
} catch (err) {
// reject every waiter with the same error
IMQLock.release('doSomething', null, err, token);
throw err;
}
}
return lock;
}
for (let i = 0; i < 10; ++i) {
doSomething().then(res => console.log(res));
}
Properties
|
Property |
Modifiers |
Type |
Description |
|---|---|---|---|
|
|
number |
Deadlock timeout in milliseconds | |
|
|
ILogger |
Logger used to log errors that appear during locked calls |
Methods
|
Method |
Modifiers |
Description |
|---|---|---|
|
|
Acquires a lock for a given key. | |
|
|
Returns true if the given key is locked, false otherwise. | |
|
|
Releases a previously acquired lock for a given key. | |
|
|
Returns the token identifying the current holder of a given key, or |
Read this page as plain markdown — no HTML, no navigation. For pasting into an LLM, or for an agent to fetch.