Deepkit Broker

Broker Atomic Locks

Deepkit Broker Locks is a simple way to create atomic locks across multiple processes or machines.

It's a simple way to ensure that only one process can execute a certain code block at a time.

Usage

import { BrokerLock } from '@deepkit/broker';

const lock = new BrokerLock(adapter);

// lock is alive for 60 seconds.
// acquisition timeout is 10 seconds.
const myLock = lock.item('my-lock', { ttl: '60s', timeout: '10s' });

async function criticalSection() {
  // Holds the lock until the function is done.
  // cleans up the lock automatically, even if the function throws an error.
  await using hold = await lock1.hold();
}

The lock supports Explicit Resource Management, which means you don't have to use a try-catch block to ensure the lock is released properly.

To manually acquire and release a lock, you can use the acquire and release methods.

// this blocks until the lock is acquired.
// or throws if timeout is reached
await myLock.acquire();

try {
  // do something critical
} finally {
  await myLock.release();
}

App Usage

A full example of how to use the BrokerLock in your application. The class is automatically available in the dependency injection container if you import the FrameworkModule. See the Getting started page for more information.

import { BrokerLock, BrokerLockItem } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';

// move this type to a shared file
type MyCriticalLock = BrokerLockItem;

class Service {
  constructor(private criticalLock: MyCriticalLock) {
  }

  async doSomethingCritical() {
    await using hold = await this.criticalLock.hold();
    
    // do something critical,
    // lock is released automatically
  }
}

const app = new App({
  providers: [
    Service,
    provide<MyCriticalLock>((lock: BrokerLock) => lock.item('my-critical-lock', { ttl: '60s', timeout: '10s' })),
  ],
  imports: [
    new FrameworkModule(),
  ],
});