Skip to content
awekrx edited this page May 29, 2026 · 1 revision

lock

Import

import { lock } from '@dev-suite/decorators/lock'

Category

  • method

Use Case

Prevent overlapping method execution for critical sections.

Replaces

  • Manual mutex/boolean guard patterns
  • Repeated race-condition boilerplate

Example 1

Without decorator

class WalletService {
  private busy = false;

  async transfer(input: TransferInput) {
    if (this.busy) throw new Error('transfer in progress');
    this.busy = true;
    try {
      return await this.engine.transfer(input);
    } finally {
      this.busy = false;
    }
  }
}

With decorator

import { lock } from '@dev-suite/decorators/lock';

class WalletService {
  @lock()
  async transfer(input: TransferInput) {
    return this.engine.transfer(input);
  }
}

Why better

  • Critical section is declared at method level.
  • Avoids forgotten unlock paths in error branches.

Example 2

Without decorator

class SequenceService {
  private locks = new Map<string, boolean>();

  async next(sequence: string) {
    if (this.locks.get(sequence)) throw new Error('locked');
    this.locks.set(sequence, true);
    try {
      return await this.repo.next(sequence);
    } finally {
      this.locks.delete(sequence);
    }
  }
}

With decorator

import { lock } from '@dev-suite/decorators/lock';

class SequenceService {
  @lock({ keyResolver: ([sequence]) => String(sequence) })
  async next(sequence: string) {
    return this.repo.next(sequence);
  }
}

Why better

  • Supports per-key locking for independent resources.
  • Cleaner than hand-rolled lock maps.

Clone this wiki locally