I’m trying to configure a Redis session store for my NestJS application using Telegraf’s @telegraf/session/redis package. I’ve implemented the reconnection logic within the RedisClientEventListener class, but the client doesn’t seem to reconnect automatically when the Redis server crashes or restarts.
Here’s the relevant code from redis.config.ts:
import { SessionStore, session } from 'telegraf';
import { Redis } from '@telegraf/session/redis';
import { Inject, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { CACHE_MANAGER, CacheModuleAsyncOptions } from '@nestjs/cache-manager';
import { Cache } from 'cache-manager';
import { UserLangSession } from 'src/types/general';
import { CreateUserDto } from 'src/dto/create-user.dto';
import { RedisClientType } from '@redis/client';
export const store = Redis({
url: process.env.REDIS_URL,
config: {
socket: {
reconnectStrategy(retries, cause) {
console.error('error', cause);
return Math.min(retries * 1000, 5000);
},
},
},
}) as SessionStore<UserLangSession>;
export const RedisOptions: CacheModuleAsyncOptions = {
isGlobal: true,
useFactory: async () => {
return {
store: () => store,
ttl: 5000,
};
},
};
export const sessionMiddleware = () => {
return session({
store,
defaultSession: () => ({
lang: undefined,
user_info: {} as CreateUserDto,
is_authorized: false,
is_first_login: true,
animation_file_id: undefined,
}),
});
};
export class RedisClientEventListener implements OnModuleInit, OnModuleDestroy {
private readonly logger = new Logger(RedisClientEventListener.name);
private readonly redisClient: RedisClientType;
private reconnectAttempts = 0;
constructor(@Inject(CACHE_MANAGER) readonly cacheManager: Cache) {
this.redisClient = (cacheManager.store as any).client;
this.logger.log(this.redisClient);
}
onModuleInit(): void {
this.logger.log('Starting RedisClientEventListener...');
if (!this.redisClient) {
this.logger.error('No Redis client initialized');
return;
}
this.setupEventListeners(this.redisClient);
}
setupEventListeners(client: RedisClientType) {
client.on('connect', () => {
this.logger.log('Redis client is connecting to server...');
this.reconnectAttempts = 0;
});
client.on('ready', () => {
this.logger.log('Redis client is ready');
});
client.on('end', () => {
this.logger.log('Redis client connection closed');
});
client.on('error', (error: Error) => {
this.logger.error('Redis client received an error', error.message);
this.reconnect(client);
});
client.on('reconnecting', (delay: number) => {
this.logger.log(`Redis client reconnecting in ${delay}ms`);
});
client.on('close', () => {
this.logger.warn('Redis client connection closed unexpectedly');
this.reconnect(client);
});
}
async reconnect(client: RedisClientType): Promise<void> {
this.reconnectAttempts++;
const reconnectDelay = Math.min(this.reconnectAttempts * 1000, 5000);
this.logger.log(
`Redis client reconnection attempt ${this.reconnectAttempts}. Delaying for ${reconnectDelay}ms.`,
);
await new Promise((resolve) => setTimeout(resolve, reconnectDelay));
try {
await client.connect();
} catch (error) {
this.logger.error('Redis client reconnection failed:', error);
}
}
async onModuleDestroy(): Promise<void> {
await this.redisClient.quit();
}
}
config.module.ts
import { Global, Module } from '@nestjs/common';
import * as NestConfig from '@nestjs/config';
import { CacheModule } from '@nestjs/cache-manager';
@Global()
@Module({
imports: [
NestConfig.ConfigModule.forRoot({
envFilePath: ['.env'],
isGlobal: true,
}),
CacheModule.registerAsync(RedisOptions),
],
})
export class ConfigModule {}
Questions:
Are there any additional configurations or dependencies required for automatic reconnection in NestJS with Telegraf and Redis?
Could there be any potential issues with accessing the underlying Redis client through cacheManager.store.client?
Are there any best practices for debugging and troubleshooting reconnection issues in this scenario?
Thnx in advance!
Additional Information:
NestJS version: 10.3.2
“telegraf”: “^4.16.3”,
“nestjs-telegraf”: “^2.7.0”,
“@telegraf/session”: “^2.0.0-beta.7”,
“@nestjs/cache-manager”: “^2.2.2”,
“cache-manager”: “^5.5.3”,
“redis”: “^4.6.13”
I expected the code to utilize the reconnectStrategy function within socket configuration for automatic reconnection upon Redis server crashes or restarts. However, there might be issues with how the client instance is accessed.
nomaddos is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.