Files
SerpentRace/SerpentRace_Backend/dist/Application/Services/RedisService.js
T

273 lines
9.3 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.RedisService = void 0;
const redis_1 = require("redis");
const Logger_1 = require("./Logger");
class RedisService {
constructor() {
this.isConnected = false;
const redisUrl = process.env.REDIS_URL || 'redis://localhost:6379';
this.client = (0, redis_1.createClient)({
url: redisUrl,
socket: {
reconnectStrategy: (retries) => Math.min(retries * 50, 500)
}
});
this.client.on('error', (err) => {
(0, Logger_1.logError)('Redis connection error', err);
this.isConnected = false;
});
this.client.on('connect', () => {
(0, Logger_1.logStartup)('Redis client connected successfully');
this.isConnected = true;
});
this.client.on('disconnect', () => {
(0, Logger_1.logWarning)('Redis client disconnected');
this.isConnected = false;
});
}
static getInstance() {
if (!RedisService.instance) {
RedisService.instance = new RedisService();
}
return RedisService.instance;
}
async connect() {
try {
if (!this.isConnected) {
await this.client.connect();
}
}
catch (error) {
(0, Logger_1.logError)('Failed to connect to Redis', error);
throw error;
}
}
async disconnect() {
try {
if (this.isConnected) {
await this.client.disconnect();
}
}
catch (error) {
(0, Logger_1.logError)('Failed to disconnect from Redis', error);
}
}
async setActiveChat(chatId, chatData) {
try {
const key = `active_chat:${chatId}`;
await this.client.hSet(key, {
chatId: chatData.chatId,
participants: JSON.stringify(chatData.participants),
lastActivity: chatData.lastActivity.toISOString(),
messageCount: chatData.messageCount.toString(),
chatType: chatData.chatType,
gameId: chatData.gameId || '',
name: chatData.name || ''
});
// Set expiration for 1 hour of inactivity
await this.client.expire(key, 3600);
}
catch (error) {
(0, Logger_1.logError)(`Failed to set active chat ${chatId}`, error);
}
}
async getActiveChat(chatId) {
try {
const key = `active_chat:${chatId}`;
const data = await this.client.hGetAll(key);
if (!data.chatId) {
return null;
}
return {
chatId: data.chatId,
participants: JSON.parse(data.participants),
lastActivity: new Date(data.lastActivity),
messageCount: parseInt(data.messageCount, 10),
chatType: data.chatType,
gameId: data.gameId || undefined,
name: data.name || undefined
};
}
catch (error) {
(0, Logger_1.logError)(`Failed to get active chat ${chatId}`, error);
return null;
}
}
async removeActiveChat(chatId) {
try {
const key = `active_chat:${chatId}`;
await this.client.del(key);
}
catch (error) {
(0, Logger_1.logError)(`Failed to remove active chat ${chatId}`, error);
}
}
async getAllActiveChats() {
try {
const pattern = 'active_chat:*';
const keys = await this.client.keys(pattern);
const chats = [];
for (const key of keys) {
const data = await this.client.hGetAll(key);
if (data.chatId) {
chats.push({
chatId: data.chatId,
participants: JSON.parse(data.participants),
lastActivity: new Date(data.lastActivity),
messageCount: parseInt(data.messageCount, 10),
chatType: data.chatType,
gameId: data.gameId || undefined,
name: data.name || undefined
});
}
}
return chats;
}
catch (error) {
(0, Logger_1.logError)('Failed to get all active chats', error);
return [];
}
}
async setActiveUser(userId, userData) {
try {
const key = `active_user:${userId}`;
await this.client.hSet(key, {
userId: userData.userId,
activeChatIds: JSON.stringify(userData.activeChatIds),
lastActivity: userData.lastActivity.toISOString(),
isOnline: userData.isOnline.toString()
});
// Set expiration for 2 hours
await this.client.expire(key, 7200);
}
catch (error) {
(0, Logger_1.logError)(`Failed to set active user ${userId}`, error);
}
}
async getActiveUser(userId) {
try {
const key = `active_user:${userId}`;
const data = await this.client.hGetAll(key);
if (!data.userId) {
return null;
}
return {
userId: data.userId,
activeChatIds: JSON.parse(data.activeChatIds),
lastActivity: new Date(data.lastActivity),
isOnline: data.isOnline === 'true'
};
}
catch (error) {
(0, Logger_1.logError)(`Failed to get active user ${userId}`, error);
return null;
}
}
async removeActiveUser(userId) {
try {
const key = `active_user:${userId}`;
await this.client.del(key);
}
catch (error) {
(0, Logger_1.logError)(`Failed to remove active user ${userId}`, error);
}
}
async addUserToChat(userId, chatId) {
try {
const userData = await this.getActiveUser(userId) || {
userId,
activeChatIds: [],
lastActivity: new Date(),
isOnline: true
};
if (!userData.activeChatIds.includes(chatId)) {
userData.activeChatIds.push(chatId);
userData.lastActivity = new Date();
await this.setActiveUser(userId, userData);
}
}
catch (error) {
(0, Logger_1.logError)(`Failed to add user ${userId} to chat ${chatId}`, error);
}
}
async removeUserFromChat(userId, chatId) {
try {
const userData = await this.getActiveUser(userId);
if (userData) {
userData.activeChatIds = userData.activeChatIds.filter(id => id !== chatId);
userData.lastActivity = new Date();
await this.setActiveUser(userId, userData);
}
}
catch (error) {
(0, Logger_1.logError)(`Failed to remove user ${userId} from chat ${chatId}`, error);
}
}
async getUserActiveChats(userId) {
try {
const userData = await this.getActiveUser(userId);
return userData?.activeChatIds || [];
}
catch (error) {
(0, Logger_1.logError)(`Failed to get active chats for user ${userId}`, error);
return [];
}
}
async updateChatActivity(chatId, messageCount) {
try {
const chatData = await this.getActiveChat(chatId);
if (chatData) {
chatData.lastActivity = new Date();
if (messageCount !== undefined) {
chatData.messageCount = messageCount;
}
await this.setActiveChat(chatId, chatData);
}
}
catch (error) {
(0, Logger_1.logError)(`Failed to update chat activity ${chatId}`, error);
}
}
async getInactiveChats(inactivityMinutes) {
try {
const cutoffTime = new Date(Date.now() - inactivityMinutes * 60 * 1000);
const allChats = await this.getAllActiveChats();
return allChats
.filter(chat => chat.lastActivity < cutoffTime)
.map(chat => chat.chatId);
}
catch (error) {
(0, Logger_1.logError)('Failed to get inactive chats', error);
return [];
}
}
async cleanupInactiveChats(inactivityMinutes) {
try {
const inactiveChats = await this.getInactiveChats(inactivityMinutes);
for (const chatId of inactiveChats) {
await this.removeActiveChat(chatId);
}
return inactiveChats;
}
catch (error) {
(0, Logger_1.logError)('Failed to cleanup inactive chats', error);
return [];
}
}
async ping() {
try {
const result = await this.client.ping();
return result === 'PONG';
}
catch (error) {
(0, Logger_1.logError)('Redis ping failed', error);
return false;
}
}
isRedisConnected() {
return this.isConnected;
}
}
exports.RedisService = RedisService;
//# sourceMappingURL=RedisService.js.map