npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@damon35868/nestjs-simple-redis-lock

v1.1.4

Published

Distributed lock with single redis instance, simple and easy to use for Nestjs

Downloads

19

Readme

@damon35868/nestjs-simple-redis-lock

Distributed lock with single redis instance, simple and easy to use for Nestjs

Installation

npm install @damon35868/nestjs-simple-redis-lock

Usage

You must install nestjs-redis, and use in Nest. This package use it to access redis:

// app.ts
import { RedisLockModule } from '@damon35868/nestjs-simple-redis-lock';

@Module({
  imports: [
    ...
    RedisModule.forRootAsync({ // import RedisModule before RedisLockModule
      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({
     // isGlobal: true,
      useFactory: async (redisManager: RedisManager) => {
        return { prefix: ':lock:', client: redisManager.getClient() }
      },
      inject: [RedisManager]
    }), // import RedisLockModule, use default configuration
  ]
})
export class AppModule {}

New Feature

default single is true

import { RedisLockService } from '@damon35868/nestjs-simple-redis-lock';

export class FooService {
  constructor(
    protected readonly lockService: RedisLockService, // inject RedisLockService
  ) {}

  async test1() {
    try {
      /**
       * Get a lock by name
       * Automatically unlock after 1min
       * Try again after 100ms
       * The max times to retry is 36000, about 1h
       */

      // default single is true
      await this.lockService.lock('test1', { single:true });
      // Do somethings
    } catch(e:any){
      // do someting on lock fail
      throw new Error(e.message || `RedisLockService: locking for ***, please try later`);
    } inally { // use 'finally' to ensure unlocking
      this.lockService.unlock('test1'); // unlock
      // Or: await this.lockService.unlock('test1'); wait for the unlocking
    }
  }

  async test2() {
    /**
     * Automatically unlock after 2min
     * Try again after 50ms if failed
     * The max times to retry is 100
     */
    await this.lockService.lock('test1', { expire: 2 * 60 * 1000, retryInterval:50, maxRetryTimes: 100 });
    // Do somethings
    await this.lockService.setTTL('test1', 60000); // Renewal the lock when the program is very time consuming, avoiding automatically unlock
    this.lockService.unlock('test1');
  }
}

1. Simple example

import { RedisLockService } from '@damon35868/nestjs-simple-redis-lock';

export class FooService {
  constructor(
    protected readonly lockService: RedisLockService, // inject RedisLockService
  ) {}

  async test1() {
    try {
      /**
       * Get a lock by name
       * Automatically unlock after 1min
       * Try again after 100ms
       * The max times to retry is 36000, about 1h
       */
      await this.lockService.lock('test1');
      // Do somethings
    } finally { // use 'finally' to ensure unlocking
      this.lockService.unlock('test1'); // unlock
      // Or: await this.lockService.unlock('test1'); wait for the unlocking
    }
  }

  async test2() {
    /**
     * Automatically unlock after 2min
     * Try again after 50ms if failed
     * The max times to retry is 100
     */
    await this.lockService.lock('test1', { expire: 2 * 60 * 1000, retryInterval:50, maxRetryTimes: 100 });
    // Do somethings
    await this.lockService.setTTL('test1', 60000); // Renewal the lock when the program is very time consuming, avoiding automatically unlock
    this.lockService.unlock('test1');
  }
}

2. Example by using decorator

Using @damon35868/nestjs-simple-redis-lock by decorator, the locking and unlocking will be very easy. Simple example with constant lock name:

import { RedisLockService, RedisLock } from '@damon35868/nestjs-simple-redis-lock';

export class FooService {
  constructor(
    protected readonly lockService: RedisLockService, // inject RedisLockService
  ) {}

  /**
   * Wrap the method, starting with getting a lock, ending with unlocking
   * The first parameter is lock name
   * By default, automatically unlock after 1min.
   * By default, try again after 100ms if failed
   * By default, the max times to retry is 36000, about 1h
   */
  @RedisLock('test2')
  async test1() {
    // Do somethings
    return 'some values';
  }

  /**
   * Automatically unlock after 2min
   * Try again after 50ms if failed
   * The max times to retry is 100
   */
  @RedisLock('test2', { expire: 2 * 60 * 1000, retryInterval:50, maxRetryTimes: 100 })
  async test2() {
    // Do somethings
    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 '@damon35868/nestjs-simple-redis-lock';

export class FooService {
  lockName = 'test3';

  constructor(
    protected readonly lockService: RedisLockService, // inject RedisLockService
  ) {}

  /**
   * Determinate lock name from 'this'
   * The first parameter is 'this', so you can access any member in 'this' for create a dynamic lock name.
   */
  @RedisLock((target) => target.lockName)
  async test1() {
    // Do somethings
    return 'some values';
  }

  /**
   * Determinate lock name from the parameters of the method
   * The original parameters also pass to the function, so you can determinate the lock name by the parameters.
   */
  @RedisLock((target, param1, param2) => param1 + param2)
  async test2(param1, param2) {
    // Do somethings
    return 'some values';
  }
}

Configuration

  • Register:*
@Module({
  imports: [
    RedisLockModule.register({
      clientName: 'client_name', // the Redis client name in nestjs-redis, to use specific Redis client. Default to use default client
      prefix: 'my_lock:', // By default, the prefix is '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:

// package.json
{
  "scripts": {
    "start:dev": "DEBUG=nestjs-simple-redis-lock tsc-watch -p tsconfig.build.json --onSuccess \"node dist/main.js\""
  }
}