135 lines
3.9 KiB
JavaScript
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;
|
|
} |