Skip to content

Instantly share code, notes, and snippets.

@ali-master
Last active April 9, 2024 21:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ali-master/aaf2f4bbde33445ff94197994287abf9 to your computer and use it in GitHub Desktop.
Save ali-master/aaf2f4bbde33445ff94197994287abf9 to your computer and use it in GitHub Desktop.
Nestjs Redis Lock
import { Global, Module } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
@Global()
@Module({
providers: [
{
provide: LockService,
inject: [ConfigService],
useFactory: async (configService: ConfigService) => {
const service = new LockService(configService);
await service.init();
return service;
},
},
],
exports: [LockService],
})
export class LockModule {}
import { Injectable } from "@nestjs/common";
import { RedisClientType, createClient } from "redis";
@Injectable()
export class LockService {
private client: RedisClientType;
constructor(private readonly configService: ConfigService) {
this.client = createClient({
url: this.configService.get<string>("redis.url"),
});
}
async init() {
await this.client.connect();
}
private async lock(
key: string,
value: string,
ttlMs: number,
): Promise<boolean> {
return (
(await this.client.set(key, value, {
NX: true,
PX: ttlMs,
})) === "OK"
);
}
private async unlock(key: string) {
return await this.client.del([key]);
}
async tryLockOnce(
key: string,
value: string,
ttlMs: number,
handler: () => Promise<unknown>,
) {
if (!(await this.lock(key, value, ttlMs))) {
return;
}
try {
await handler();
} finally {
await this.unlock(key);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment