Open lakshmipriyamukundan opened 3 years ago
this is how I do this with cache-manager-redis-store
of version 2:
// `redis-cache.module.ts` file
import {
CacheModule,
CACHE_MANAGER,
Inject,
Logger,
Module,
OnModuleDestroy,
} from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import type { ClientOpts } from 'redis';
import { Cache } from 'cache-manager';
import { RedisCacheStoreProvider } from './redis-cache-store.provider';
@Module({
imports: [
ConfigModule,
CacheModule.registerAsync<ClientOpts>({
imports: [RedisCacheModule],
useFactory: async (redisCacheStoreProvider: RedisCacheStoreProvider) => {
return {
store: await redisCacheStoreProvider.build(),
};
},
inject: [RedisCacheStoreProvider],
isGlobal: true,
}),
],
providers: [RedisCacheStoreProvider],
exports: [RedisCacheStoreProvider],
})
export class RedisCacheModule implements OnModuleDestroy {
private readonly logger: Logger = new Logger(RedisCacheModule.name);
constructor(@Inject(CACHE_MANAGER) private cacheManager: Cache) {}
onModuleDestroy(): void {
this.logger.log('Closing Redis cache connection');
const client = this.cacheManager.store.getClient();
// https://github.com/nestjs/nest/issues/8020
client.quit();
}
}
// ---------------------------------------------------------------------------------------
// `redis-cache-store.provider.ts` file
import redisStore from 'cache-manager-redis-store';
import { Inject, Logger, Injectable } from '@nestjs/common';
import { ConfigType } from '@nestjs/config';
import { redisRetryCallback } from './redis-retry-callback';
import { redisConfig } from 'config';
@Injectable()
export class RedisCacheStoreProvider {
private readonly logger = new Logger(RedisCacheStoreProvider.name);
constructor(
@Inject(redisConfig.KEY)
private config: ConfigType<typeof redisConfig>,
) {}
async build() {
const store = await redisStore.create({
host: this.config.host,
port: this.config.port,
// https://github.com/node-cache-manager/node-cache-manager/issues/51
enable_offline_queue: false,
retryStrategy: redisRetryCallback(this.config, this.logger),
});
return store;
}
}
// ---------------------------------------------------------------------------------------
// `redis-retry-callback.ts` file
import { RetryStrategyOptions } from '@nestjs/microservices/external/redis.interface';
import { Logger } from '@nestjs/common';
import * as Sentry from '@sentry/node';
import { IRedisConfig } from 'config';
interface RedisRetryStrategyOptions
// in fact `total_retry_time` and `times_connected` properties are given in camelCase notation - idk why
extends Omit<RetryStrategyOptions, 'total_retry_time' | 'times_connected'> {
// so we manually override the interface
totalRetryTime: number;
timesConnected: number;
}
export const redisRetryCallback =
(redisConfig: IRedisConfig, logger: Logger) =>
({ error, attempt, totalRetryTime, timesConnected }: RedisRetryStrategyOptions) => {
const { retryDelay, retryAttempts } = redisConfig;
if (attempt > retryAttempts) {
logger.error(`Redis connection retry time exhausted`, {
totalRetryTime,
timesConnected,
retryDelay,
retryAttempts,
});
throw new Error('Redis connection retry time exhausted');
}
if (error) {
logger.error(`Redis connection error. Attempt: ${attempt}. Error: ${error}`);
Sentry.captureMessage('Redis connection error.', {
extra: {
attempt,
totalRetryTime,
timesConnected,
retryDelay,
retryAttempts,
},
});
}
return retryDelay;
};