All files / app/storage redisClient.ts

36.36% Statements 16/44
100% Branches 2/2
50% Functions 2/4
36.36% Lines 16/44

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 454x 4x 4x 4x 4x 4x 4x 4x 4x 4x 4x 1x 1x                                           1x 1x               1x  
import { createClient, SetOptions } from 'redis';
import { Logger } from '../utils/logger.js';
 
export type RedisClient = ReturnType<typeof createClient>;
export type RedisSetOptions = SetOptions;
 
const RECONNECT_MAX_RETRY = 10;
const RECONNECT_DELAY = 100;
 
export class RedisClientInstance {
  private static redisClient: RedisClient | undefined;
 
  public static async getRedisClient(redisUrl = process.env.REDIS_URL || 'localhost:6379'): Promise<RedisClient> {
    if (!RedisClientInstance.redisClient) {
      RedisClientInstance.redisClient = createClient({
        url: `redis://${redisUrl}`,
        socket: {
          reconnectStrategy: (retries, cause) => {
            if (retries > RECONNECT_MAX_RETRY) {
              return false;
            }
            Logger.log('Redis client reconnect retries', retries);
            Logger.error('Redis client reconnect cause', cause);
            return RECONNECT_DELAY * retries;
          },
        },
      });

      RedisClientInstance.redisClient.on('error', (err: unknown) => Logger.error('Redis client error', err));
      await RedisClientInstance.redisClient.connect();
    }

    return RedisClientInstance.redisClient;
  }
 
  public static async disconnectClient(): Promise<void> {
    if (!RedisClientInstance.redisClient) {
      return;
    }

    await RedisClientInstance.redisClient.close();
    RedisClientInstance.redisClient = undefined;
  }
}