| import Redis from 'ioredis'; |
|
|
| import { config } from '@/config'; |
| import logger from '@/utils/logger'; |
|
|
| import type CacheModule from './base'; |
|
|
| const status = { available: false }; |
| const clients: { |
| redisClient?: Redis; |
| } = {}; |
|
|
| const getCacheTtlKey = (key: string) => { |
| if (key.startsWith('rsshub:cacheTtl:')) { |
| throw new Error('"rsshub:cacheTtl:" prefix is reserved for the internal usage, please change your cache key'); |
| } |
| return `rsshub:cacheTtl:${key}`; |
| }; |
|
|
| export default { |
| init: () => { |
| clients.redisClient = new Redis(config.redis.url); |
|
|
| clients.redisClient.on('error', (error) => { |
| status.available = false; |
| logger.error('Redis error: ', error); |
| }); |
| clients.redisClient.on('end', () => { |
| status.available = false; |
| }); |
| clients.redisClient.on('connect', () => { |
| status.available = true; |
| logger.info('Redis connected.'); |
| }); |
| }, |
| get: async (key: string, refresh = true) => { |
| if (key && status.available && clients.redisClient) { |
| const cacheTtlKey = getCacheTtlKey(key); |
| let [value, cacheTtl] = await clients.redisClient.mget(key, cacheTtlKey); |
| if (value && refresh) { |
| if (cacheTtl) { |
| clients.redisClient.expire(cacheTtlKey, cacheTtl); |
| } else { |
| |
| cacheTtl = config.cache.contentExpire + ''; |
| |
| |
| } |
| clients.redisClient.expire(key, cacheTtl); |
| value = value + ''; |
| } |
| return value || ''; |
| } else { |
| return null; |
| } |
| }, |
| set: (key: string, value?: string | Record<string, any>, maxAge = config.cache.contentExpire) => { |
| if (!status.available || !clients.redisClient) { |
| return; |
| } |
| if (!value || value === 'undefined') { |
| value = ''; |
| } |
| if (typeof value === 'object') { |
| value = JSON.stringify(value); |
| } |
| if (key) { |
| if (maxAge !== config.cache.contentExpire) { |
| |
| clients.redisClient.set(getCacheTtlKey(key), maxAge, 'EX', maxAge); |
| } |
| return clients.redisClient.set(key, value, 'EX', maxAge); |
| } |
| }, |
| clients, |
| status, |
| } as CacheModule; |
|
|