@oro-dxeco/nestjs-simple-redis-lock
Distributed lock with single redis instance, simple and easy to use for Nestjs
Installation
npm install @oro-dxeco/nestjs-simple-redis-lock
Usage
You must install nestjs-redis, and use in Nest. This package use it to access redis:
import { RedisLockModule } from '@oro-dxeco/nestjs-simple-redis-lock';
@Module({
imports: [
...
RedisModule.forRootAsync({
imports: [ConfigModule],
useFactory: (config: ConfigService) => ({
host: config.get('REDIS_HOST'),
port: config.get('REDIS_PORT'),
db: parseInt(config.get('REDIS_DB'), 10),
password: config.get('REDIS_PASSWORD'),
keyPrefix: config.get('REDIS_KEY_PREFIX'),
}),
inject: [ConfigService],
}),
RedisLockModule.registerAsync({
useFactory: async (redisManager: RedisManager) => {
return { prefix: ':lock:', client: redisManager.getClient() }
},
inject: [RedisManager]
}),
]
})
export class AppModule {}
1. Simple example
import { RedisLockService } from '@oro-dxeco/nestjs-simple-redis-lock';
export class FooService {
constructor(
protected readonly lockService: RedisLockService,
) {}
async test1() {
try {
await this.lockService.lock('test1');
} finally {
this.lockService.unlock('test1');
}
}
async test2() {
await this.lockService.lock('test1', 2 * 60 * 1000, 50, 100);
await this.lockService.setTTL('test1', 60000);
this.lockService.unlock('test1');
}
}
2. Example by using decorator
Using @oro-dxeco/nestjs-simple-redis-lock by decorator, the locking and unlocking will be very easy.
Simple example with constant lock name:
import { RedisLockService, RedisLock } from '@oro-dxeco/nestjs-simple-redis-lock';
export class FooService {
constructor(
protected readonly lockService: RedisLockService,
) {}
@RedisLock('test2')
async test1() {
return 'some values';
}
@RedisLock('test2', 2 * 60 * 1000, 50, 100)
async test2() {
return 'some values';
}
}
The first parameter of this decorator is a powerful function. It can use to determinate lock name by many ways.
Simple example with dynamic lock name:
import { RedisLockService, RedisLock } from '@oro-dxeco/nestjs-simple-redis-lock';
export class FooService {
lockName = 'test3';
constructor(
protected readonly lockService: RedisLockService,
) {}
@RedisLock((target) => target.lockName)
async test1() {
return 'some values';
}
@RedisLock((target, param1, param2) => param1 + param2)
async test2(param1, param2) {
return 'some values';
}
}
Configuration
@Module({
imports: [
RedisLockModule.register({
clientName: 'client_name',
prefix: 'my_lock:',
})
]
})
Async register:
@Module({
imports: [
RedisLockModule.registerAsync({
imports: [ConfigModule],
useFactory: async (config: ConfigService) => ({
clientName: config.get('REDIS_LOCK_CLIENT_NAME')
}),
inject: [ConfigService],
}),
]
})
Debug
Add a environment variable DEBUG=nestjs-simple-redis-lock when start application to check log:
{
"scripts": {
"start:dev": "DEBUG=nestjs-simple-redis-lock tsc-watch -p tsconfig.build.json --onSuccess \"node dist/main.js\""
}
}