- 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
46 lines
1.3 KiB
TypeScript
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;
|