Skip to content

da440dil/js-rlock

Repository files navigation

@da440dil/rlock

CI Coverage Status

Distributed locking using Redis.

Supports ioredis and node-redis.

Example single key locking with ioredis:

import { setTimeout } from 'node:timers/promises';
import Redis from 'ioredis';
import { RLock } from '@da440dil/rlock';

const client = new Redis();
const rlock = RLock.io(client);

async function main() {
	const lock1 = await rlock.lock(['k1'], 200);
	if (!lock1.ok) {
		console.log('Lock1 failed');
		return;
	}
	console.log('Lock1 acquired');

	const lock2 = await rlock.lock(['k1'], 200);
	if (!lock2.ok) {
		console.log('Lock2 failed');
		await setTimeout(lock2.ttl);
		const ok = await lock2.lock(200);
		if (!ok) {
			console.log('Lock2 failed');
			return;
		}
		console.log('Lock1 timed out\nLock2 acquired');
	}

	const ok = await lock2.unlock();
	if (ok) {
		console.log('Lock2 released');
	} else {
		console.log('Lock2 timed out');
	}
	// Output:
	// Lock1 acquired
	// Lock2 failed
	// Lock1 timed out
	// Lock2 acquired
	// Lock2 released
}

main().catch(console.error).finally(() => client.quit());
npm run file examples/lock1.ts

Example multiple keys locking with node-redis:

import { setTimeout } from 'node:timers/promises';
import { createClient } from 'redis';
import { RLock } from '@da440dil/rlock';

const client = createClient();
const rlock = RLock.node(client);

async function main() {
	await client.connect();
	const lock1 = await rlock.lock(['k1', 'k2']);
	const lock2 = await rlock.lock(['k1', 'k3']);
	const lock3 = await rlock.lock(['k2', 'k3']);
	const ttl = 200;

	console.log(`Lock1: lock => ${await lock1.lock(ttl)}`);
	console.log(`Lock2: lock => ${await lock2.lock(ttl)}`);
	console.log(`Lock3: lock => ${await lock3.lock(ttl)}`);
	await setTimeout(ttl);
	console.log(`Timeout: ${ttl}`);

	console.log(`Lock2: lock => ${await lock2.lock(ttl)}`);
	console.log(`Lock3: lock => ${await lock3.lock(ttl)}`);
	console.log(`Lock1: lock => ${await lock1.lock(ttl)}`);
	await setTimeout(ttl);
	console.log(`Timeout: ${ttl}`);

	console.log(`Lock3: lock => ${await lock3.lock(ttl)}`);
	console.log(`Lock1: lock => ${await lock1.lock(ttl)}`);
	console.log(`Lock2: lock => ${await lock2.lock(ttl)}`);
	// Output:
	// Lock1: lock => true
	// Lock2: lock => false
	// Lock3: lock => false
	// Timeout: 200
	// Lock2: lock => true
	// Lock3: lock => false
	// Lock1: lock => false
	// Timeout: 200
	// Lock3: lock => true
	// Lock1: lock => false
	// Lock2: lock => false
}

main().catch(console.error).finally(() => client.quit());
npm run file examples/lock2.ts