Skip to main content

Mutex - API

A mutual exclusion primitive useful for protecting shared data.

Installation

npm is the default package manager for Node.js, and to where tscommon is published.
Your project is using npm if it has a package-lock.json file in its root folder.

Run the following command in your terminal:

terminal
npm install @tscommon/mutex

Usage

Automatic Lock

main.ts
import assert from 'assert/strict';
import { setTimeout } from 'timers/promises';
import { Mutex } from '@tscommon/mutex';

const mutex = new Mutex(0);

async function increment(check: number): Promise<void> {
// It is important to use the `using` statement to acquire the lock.
await using lock = mutex.lock();
// We use the `await` keyword to wait for the lock to be acquired.
const counter = await lock;
await setTimeout(Math.random() * 1000);
assert(counter.value === check);
counter.value++;
} // The lock is automatically released when the `using` block ends.

async function main(): Promise<void> {
increment(0);
increment(1);
increment(2);
}

main();

Try Lock

main.ts
import assert from 'assert/strict';
import { setTimeout } from 'timers/promises';
import { Mutex } from '@tscommon/mutex';

const mutex = new Mutex(0);

async function increment(check: number): Promise<void> {
// It is important to use the `using` statement to acquire the lock.
await using lock = mutex.tryLock();
const counter = await lock;
if (counter) {
// We have acquired the lock.
await setTimeout(Math.random() * 1000);
assert(counter.value === check);
counter.value++;
} else {
// We have not acquired the lock.
}
} // The lock is automatically released when the `using` block ends.

async function main(): Promise<void> {
increment(0);
increment(1);
increment(2);
}

main();

Manual Lock

main.ts
import assert from 'assert/strict';
import { setTimeout } from 'timers/promises';
import { Mutex } from '@tscommon/mutex';

const mutex = new Mutex(0);

async function increment(check: number): Promise<void> {
const lock = mutex.lock();
try {
const counter = await lock;
await setTimeout(Math.random() * 1000);
assert(counter.value === check);
counter.value++;
} finally {
// It is important to release the lock in a `finally` block.
lock.release();
}
}

async function main(): Promise<void> {
increment(0);
increment(1);
increment(2);
}

main();