feat: redis cache and detach image into s3
This commit is contained in:
135
services/redis-service.mjs
Normal file
135
services/redis-service.mjs
Normal file
@@ -0,0 +1,135 @@
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user