Lock
Contract
@modularityjs/lock defines the abstract LockService:
typescript
abstract class LockService {
abstract acquire(key: string, ttlMs: number): Promise<boolean>;
abstract release(key: string): Promise<void>;
}Drivers
Memory (@modularityjs/lock-memory)
Single-process in-memory lock. For development and testing.
typescript
import { LockModule } from '@modularityjs/core';
import { LockMemoryModule } from '@modularityjs/lock-memory';
const modules = [LockModule, LockMemoryModule];Redis (@modularityjs/lock-redis)
Distributed lock using SET NX PX with Lua-based safe release (owner token pattern). Requires @modularityjs/redis.
typescript
import { LockModule } from '@modularityjs/core';
import { LockRedisModule } from '@modularityjs/lock-redis';
import { RedisModule } from '@modularityjs/redis';
const modules = [
RedisModule.forRoot({ host: 'localhost' }),
LockModule,
LockRedisModule,
];Usage
typescript
import { Inject, Injectable, LockService } from '@modularityjs/core';
@Injectable()
class PaymentService {
constructor(@Inject(LockService) private readonly lock: LockService) {}
async processPayment(orderId: string): Promise<void> {
const acquired = await this.lock.acquire(`payment:${orderId}`, 30_000);
if (!acquired) {
throw new Error('Payment already being processed');
}
try {
// critical section
} finally {
await this.lock.release(`payment:${orderId}`);
}
}
}