Skip to content

Examples

Basic lock and release

import { DistributedLock } from "dflockd-client";

const lock = new DistributedLock({
  key: "my-key",
  acquireTimeoutS: 10,
  leaseTtlS: 20,
});

await lock.acquire();
console.log(`acquired key=${lock.key} token=${lock.token} lease=${lock.lease}`);

// lock auto-renews in the background
// ... do work ...

await lock.release();

withLock helper

const lock = new DistributedLock({
  key: "my-key",
  acquireTimeoutS: 10,
  leaseTtlS: 20,
});

await lock.withLock(async () => {
  console.log(`acquired key=${lock.key} token=${lock.token}`);
  // ... do work ...
});
// lock released automatically

FIFO ordering — concurrent workers

Multiple workers competing for the same lock are granted access in FIFO order:

async function worker(id: number): Promise<void> {
  const lock = new DistributedLock({
    key: "shared-key",
    acquireTimeoutS: 30,
  });

  await lock.withLock(async () => {
    console.log(`worker ${id}: acquired`);
    await new Promise((r) => setTimeout(r, 100));
    console.log(`worker ${id}: releasing`);
  });
}

// Launch 5 workers — they acquire the lock in order
await Promise.all(Array.from({ length: 5 }, (_, i) => worker(i)));

Two-phase locking (enqueue / wait)

Split acquisition into two steps to notify an external system between joining the queue and blocking:

const lock = new DistributedLock({
  key: "two-phase-key",
  acquireTimeoutS: 10,
  leaseTtlS: 20,
});

// Step 1: join the queue (returns immediately)
const status = await lock.enqueue(); // "acquired" or "queued"

// Step 2: notify external system
console.log(`enqueue status: ${status}`);
notifyExternalSystem(status);

// Step 3: block until the lock is granted
const granted = await lock.wait(10);
if (!granted) {
  console.error("timed out waiting for lock");
  process.exit(1);
}

try {
  // critical section — lock is held and auto-renewed
} finally {
  await lock.release();
}

Semaphore — concurrent access

Allow up to N concurrent holders per key:

import { DistributedSemaphore } from "dflockd-client";

const sem = new DistributedSemaphore({ key: "worker-pool", limit: 5 });

await sem.withLock(async () => {
  // up to 5 concurrent holders
  console.log("doing work...");
});

Multi-server sharding

Distribute locks across multiple dflockd instances:

const lock = new DistributedLock({
  key: "my-resource",
  servers: [
    ["10.0.0.1", 6388],
    ["10.0.0.2", 6388],
    ["10.0.0.3", 6388],
  ],
});

await lock.withLock(async () => {
  // routed to a consistent server based on key
});

TLS

const lock = new DistributedLock({
  key: "my-resource",
  tls: {}, // uses system CA
});

// Or with a custom CA:
import * as fs from "fs";
const lock2 = new DistributedLock({
  key: "my-resource",
  tls: { ca: fs.readFileSync("ca.pem") },
});

Authentication

const lock = new DistributedLock({
  key: "my-resource",
  auth: "my-secret-token",
});

Error handling

import {
  DistributedLock,
  AcquireTimeoutError,
  AuthError,
  LockError,
} from "dflockd-client";

try {
  await lock.withLock(async () => { /* ... */ });
} catch (err) {
  if (err instanceof AcquireTimeoutError) {
    // lock could not be acquired within acquireTimeoutS
  } else if (err instanceof AuthError) {
    // authentication failed (bad or missing token)
  } else if (err instanceof LockError) {
    // protocol-level error (server disconnect, etc.)
  }
}