# 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 ```ts 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 ```ts 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` — acquires if no unexpired entry for `key` exists. - `release(key): Promise` — removes the entry. ## Implementation Notes `isLocked` uses a probe 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.