Files
dsas-cca-backend/services/redis-service.mjs
2025-05-09 19:43:01 -04:00

135 lines
3.9 KiB
JavaScript

// services/redis-service.mjs
import Redis from 'ioredis';
import dotenv from 'dotenv';
import { logger } from '../utils/logger.mjs';
dotenv.config();
const redisUrl = process.env.REDIS_URL;
let redisClient;
export const ACTIVITY_KEY_PREFIX = 'activity:'; // Exported for use in cache-manager
const STAFF_KEY = 'staffs:all';
try {
if (redisUrl) {
redisClient = new Redis(redisUrl);
redisClient.on('connect', () => {
logger.info('Connected to Redis successfully!');
});
redisClient.on('error', (err) => {
logger.error('Redis connection error:', err);
});
} else {
logger.error('REDIS_URL not defined. Redis client not initialized.');
}
} catch (error) {
logger.error('Failed to initialize Redis client:', error);
}
/**
* Gets activity data from Redis.
* @param {string} activityId
* @returns {Promise<object|null>} Parsed JSON object or null if not found/error.
*/
export async function getActivityData(activityId) {
if (!redisClient) {
logger.warn('Redis client not available, skipping getActivityData');
return null;
}
try {
const data = await redisClient.get(`${ACTIVITY_KEY_PREFIX}${activityId}`);
return data ? JSON.parse(data) : null;
} catch (err) {
logger.error(`Error getting activity ${activityId} from Redis:`, err);
return null;
}
}
/**
* Sets activity data in Redis.
* @param {string} activityId
* @param {object} data The activity data object.
* @returns {Promise<void>}
*/
export async function setActivityData(activityId, data) {
if (!redisClient) {
logger.warn('Redis client not available, skipping setActivityData');
return;
}
try {
await redisClient.set(`${ACTIVITY_KEY_PREFIX}${activityId}`, JSON.stringify(data));
} catch (err) {
logger.error(`Error setting activity ${activityId} in Redis:`, err);
}
}
/**
* Gets staff data from Redis.
* @returns {Promise<object|null>} Parsed JSON object or null if not found/error.
*/
export async function getStaffData() {
if (!redisClient) {
logger.warn('Redis client not available, skipping getStaffData');
return null;
}
try {
const data = await redisClient.get(STAFF_KEY);
return data ? JSON.parse(data) : null;
} catch (err) {
logger.error('Error getting staff data from Redis:', err);
return null;
}
}
/**
* Sets staff data in Redis.
* @param {object} data The staff data object.
* @returns {Promise<void>}
*/
export async function setStaffData(data) {
if (!redisClient) {
logger.warn('Redis client not available, skipping setStaffData');
return;
}
try {
await redisClient.set(STAFF_KEY, JSON.stringify(data));
} catch (err) {
logger.error('Error setting staff data in Redis:', err);
}
}
/**
* Gets all activity keys from Redis.
* This can be resource-intensive on large datasets. Use with caution.
* @returns {Promise<string[]>} An array of keys.
*/
export async function getAllActivityKeys() {
if (!redisClient) {
logger.warn('Redis client not available, skipping getAllActivityKeys');
return [];
}
try {
// Using SCAN for better performance than KEYS on production Redis
let cursor = '0';
const keys = [];
do {
const [nextCursor, foundKeys] = await redisClient.scan(cursor, 'MATCH', `${ACTIVITY_KEY_PREFIX}*`, 'COUNT', '100');
keys.push(...foundKeys);
cursor = nextCursor;
} while (cursor !== '0');
logger.info(`Found ${keys.length} activity keys in Redis using SCAN.`);
return keys;
} catch (err) {
logger.error('Error getting all activity keys from Redis using SCAN:', err);
return []; // Fallback or indicate error
}
}
export function getRedisClient() {
return redisClient;
}