Files
EpicNext-Cms/src/lib/redis.ts
T
openhands 65e3915a5f
CI / check (push) Successful in 31s
CI / release (push) Skipped
CI / deploy (push) Successful in 57s
feat: replace Redis with DragonflyDB
- Replace Redis server with DragonflyDB v1.40.1 (Redis protocol compatible)
- Stop redis-server service, enable dragonfly service on 127.0.0.1:6379
- Configure dragonfly in /etc/dragonfly/dragonfly.conf (bind 127.0.0.1, maxmemory 2gb)
- Update .env: remove REDIS_URL reference

Improve database reliability:
- Fix catalog-tree.ts: remove CAST(page_id AS CHAR) to enable index usage (122 rows vs 78k full scan)
- Fix catalog-repair.ts: replace sql.raw() string interpolation with parameterized sql queries using quoteIdentifier()
- Improve redis retry resilience: change retryStrategy to not give up after 3 attempts, enabling automatic reconnect after server restart

Update documentation:
- Update README: replace Redis references with DragonflyDB, add DragonflyDB setup section, update performance features list, update architecture diagram
- biome and typecheck pass clean
2026-08-12 14:34:29 +02:00

46 lines
1.3 KiB
TypeScript

import "server-only";
import Redis from "ioredis";
import { env } from "@/env";
import { logger } from "@/lib/logger";
const globalForRedis = globalThis as unknown as {
redis?: Redis | null;
redisMissingWarned?: boolean;
};
function createRedis(): Redis | null {
const url = env.REDIS_URL;
if (!url) {
if (env.NODE_ENV === "production" && !globalForRedis.redisMissingWarned) {
globalForRedis.redisMissingWarned = true;
logger.error(
"[redis] REDIS_URL is unset in production. Rate limits, site-settings cache, and JWT session invalidation fall back to in-process memory and will not work correctly across multiple instances or restarts. Set REDIS_URL in .env.",
);
}
return null;
}
try {
const client = new Redis(url, {
maxRetriesPerRequest: 3,
retryStrategy(times) {
return Math.min(times * 200, 5000);
},
lazyConnect: true,
});
client.on("error", (err) => {
logger.warn("[redis] Connection error", { error: String(err) });
});
return client;
} catch (err) {
logger.warn("[redis] Failed to create Redis client", {
error: String(err),
});
return null;
}
}
export const redis: Redis | null =
globalForRedis.redis !== undefined ? globalForRedis.redis : createRedis();
if (globalForRedis.redis === undefined) globalForRedis.redis = redis;