Files
skills/docs/persistence/database/migration/src/lock/distributed-lock/distributed-lock.md
2026-05-29 08:20:56 +01:00

2.3 KiB

distributed-lock

(no submodules)

Purpose

Provides a DistributedMigrationLock that coordinates migration locking across multiple application instances using a pluggable DistributedLockAdapter. Also exports InMemoryDistributedLockAdapter for testing and single-node use. The distributed lock uses the same exponential back-off polling strategy as the memory lock, delegating actual lock storage to the adapter.

Features

  • DistributedMigrationLock — delegates to any DistributedLockAdapter with configurable key and ttl.
  • InMemoryDistributedLockAdapter — TTL-based in-memory adapter for testing without external infrastructure.
  • Exponential back-off polling from 50 ms up to 1 s ceiling.

Usage: Basic Example

import { DistributedMigrationLock, InMemoryDistributedLockAdapter } from "@suaveplan/migration";

const lock = new DistributedMigrationLock({
  adapter: new InMemoryDistributedLockAdapter(),
  key: "app_migration_lock",
  ttl: 60_000,
});

const acquired = await lock.acquire(30_000);

Usage: Advanced Example

import { DistributedMigrationLock } from "@suaveplan/migration";
import type { DistributedLockAdapter } from "@suaveplan/migration";

class PgAdvisoryLockAdapter implements DistributedLockAdapter {
  async acquire(key: string, ttl: number) { /* pg_try_advisory_lock */ return true; }
  async release(key: string) { /* pg_advisory_unlock */ }
}

const lock = new DistributedMigrationLock({ adapter: new PgAdvisoryLockAdapter() });

API Reference

class DistributedMigrationLock implements MigrationLockAdapter

Constructor: (config: DistributedLockConfig)

  • config.adapter — DistributedLockAdapter implementation.
  • config.key? — lock key (default "migration_lock").
  • config.ttl? — lock TTL in ms (default 60_000).

class InMemoryDistributedLockAdapter implements DistributedLockAdapter

  • acquire(key, ttl): Promise<boolean> — acquires if no unexpired entry for key exists.
  • release(key): Promise<void> — removes the entry.

Implementation Notes

isLocked uses a probe key (<key>__probe) with zero TTL to test whether anything is competing for the lock — this avoids reading lock state directly, which the interface does not expose.