File size: 1,760 Bytes
c09f67c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 | import { createLoggerWithContext } from "@midday/logger";
const logger = createLoggerWithContext("redis");
let sharedRedisClient: any = null;
let RedisClientClass: any = null;
// Dynamically load Bun's RedisClient to avoid crashing in non-Bun runtimes (e.g. trigger.dev on Node)
try {
({ RedisClient: RedisClientClass } = require("bun"));
} catch {
// Not running in Bun — cache will be unavailable
}
/**
* Resolve the Redis URL.
*
* All regions share a single Upstash Redis instance via REDIS_URL.
*/
function resolveRedisUrl(): string | undefined {
return process.env.REDIS_URL;
}
/**
* Get or create a shared Redis client instance.
* Returns null in non-Bun runtimes where RedisClient is unavailable.
*/
export function getSharedRedisClient(): any {
if (sharedRedisClient) {
return sharedRedisClient;
}
if (!RedisClientClass) {
return null;
}
const redisUrl = resolveRedisUrl();
if (!redisUrl) {
throw new Error(
"Redis URL not found. Set per-region REDIS_CACHE_* env vars or REDIS_URL.",
);
}
const isProduction =
process.env.NODE_ENV === "production" ||
process.env.RAILWAY_ENVIRONMENT === "production";
sharedRedisClient = new RedisClientClass(redisUrl, {
connectionTimeout: isProduction ? 10000 : 5000,
autoReconnect: true,
maxRetries: 10,
enableOfflineQueue: true,
enableAutoPipelining: true,
});
sharedRedisClient.onclose = (err: Error) => {
if (err) {
logger.error("Connection closed", { error: err.message });
}
};
// Connect eagerly so the client is ready for first use
sharedRedisClient.connect().catch((err: Error) => {
logger.error("Initial connection error", { error: err.message });
});
return sharedRedisClient;
}
|