mirror of
https://github.com/formbricks/formbricks.git
synced 2025-12-21 13:40:31 -06:00
Compare commits
2 Commits
4.1.0
...
feature/fi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6c16f7f9ed | ||
|
|
623efc28c7 |
@@ -1,97 +0,0 @@
|
||||
// This cache handler follows the @fortedigital/nextjs-cache-handler example
|
||||
// Read more at: https://github.com/fortedigital/nextjs-cache-handler
|
||||
|
||||
// @neshca/cache-handler dependencies
|
||||
const { CacheHandler } = require("@neshca/cache-handler");
|
||||
const createLruHandler = require("@neshca/cache-handler/local-lru").default;
|
||||
|
||||
// Next/Redis dependencies
|
||||
const { createClient } = require("redis");
|
||||
const { PHASE_PRODUCTION_BUILD } = require("next/constants");
|
||||
|
||||
// @fortedigital/nextjs-cache-handler dependencies
|
||||
const createRedisHandler = require("@fortedigital/nextjs-cache-handler/redis-strings").default;
|
||||
const { Next15CacheHandler } = require("@fortedigital/nextjs-cache-handler/next-15-cache-handler");
|
||||
|
||||
// Usual onCreation from @neshca/cache-handler
|
||||
CacheHandler.onCreation(() => {
|
||||
// Important - It's recommended to use global scope to ensure only one Redis connection is made
|
||||
// This ensures only one instance get created
|
||||
if (global.cacheHandlerConfig) {
|
||||
return global.cacheHandlerConfig;
|
||||
}
|
||||
|
||||
// Important - It's recommended to use global scope to ensure only one Redis connection is made
|
||||
// This ensures new instances are not created in a race condition
|
||||
if (global.cacheHandlerConfigPromise) {
|
||||
return global.cacheHandlerConfigPromise;
|
||||
}
|
||||
|
||||
// If REDIS_URL is not set, we will use LRU cache only
|
||||
if (!process.env.REDIS_URL) {
|
||||
const lruCache = createLruHandler();
|
||||
return { handlers: [lruCache] };
|
||||
}
|
||||
|
||||
// Main promise initializing the handler
|
||||
global.cacheHandlerConfigPromise = (async () => {
|
||||
/** @type {import("redis").RedisClientType | null} */
|
||||
let redisClient = null;
|
||||
// eslint-disable-next-line turbo/no-undeclared-env-vars -- Next.js will inject this variable
|
||||
if (PHASE_PRODUCTION_BUILD !== process.env.NEXT_PHASE) {
|
||||
const settings = {
|
||||
url: process.env.REDIS_URL, // Make sure you configure this variable
|
||||
pingInterval: 10000,
|
||||
};
|
||||
|
||||
try {
|
||||
redisClient = createClient(settings);
|
||||
redisClient.on("error", (e) => {
|
||||
console.error("Redis error", e);
|
||||
global.cacheHandlerConfig = null;
|
||||
global.cacheHandlerConfigPromise = null;
|
||||
});
|
||||
} catch (error) {
|
||||
console.error("Failed to create Redis client:", error);
|
||||
}
|
||||
}
|
||||
|
||||
if (redisClient) {
|
||||
try {
|
||||
console.info("Connecting Redis client...");
|
||||
await redisClient.connect();
|
||||
console.info("Redis client connected.");
|
||||
} catch (error) {
|
||||
console.error("Failed to connect Redis client:", error);
|
||||
await redisClient
|
||||
.disconnect()
|
||||
.catch(() => console.error("Failed to quit the Redis client after failing to connect."));
|
||||
}
|
||||
}
|
||||
const lruCache = createLruHandler();
|
||||
|
||||
if (!redisClient?.isReady) {
|
||||
console.error("Failed to initialize caching layer.");
|
||||
global.cacheHandlerConfigPromise = null;
|
||||
global.cacheHandlerConfig = { handlers: [lruCache] };
|
||||
return global.cacheHandlerConfig;
|
||||
}
|
||||
|
||||
const redisCacheHandler = createRedisHandler({
|
||||
client: redisClient,
|
||||
keyPrefix: "nextjs:",
|
||||
});
|
||||
|
||||
global.cacheHandlerConfigPromise = null;
|
||||
|
||||
global.cacheHandlerConfig = {
|
||||
handlers: [redisCacheHandler],
|
||||
};
|
||||
|
||||
return global.cacheHandlerConfig;
|
||||
})();
|
||||
|
||||
return global.cacheHandlerConfigPromise;
|
||||
});
|
||||
|
||||
module.exports = new Next15CacheHandler();
|
||||
76
apps/web/cache-handler.mjs
Normal file
76
apps/web/cache-handler.mjs
Normal file
@@ -0,0 +1,76 @@
|
||||
import { Next15CacheHandler } from "@fortedigital/nextjs-cache-handler/next-15-cache-handler";
|
||||
import createRedisHandler from "@fortedigital/nextjs-cache-handler/redis-strings";
|
||||
import { CacheHandler } from "@neshca/cache-handler";
|
||||
import createLruHandler from "@neshca/cache-handler/local-lru";
|
||||
import { createClient } from "redis";
|
||||
|
||||
// Function to create a timeout promise
|
||||
const createTimeoutPromise = (ms, rejectReason) => {
|
||||
return new Promise((_, reject) => setTimeout(() => reject(new Error(rejectReason)), ms));
|
||||
};
|
||||
|
||||
CacheHandler.onCreation(async () => {
|
||||
let client;
|
||||
|
||||
if (process.env.REDIS_URL) {
|
||||
try {
|
||||
// Create a Redis client.
|
||||
client = createClient({
|
||||
url: process.env.REDIS_URL,
|
||||
});
|
||||
|
||||
// Redis won't work without error handling.
|
||||
client.on("error", () => {});
|
||||
} catch (error) {
|
||||
console.warn("Failed to create Redis client:", error);
|
||||
}
|
||||
|
||||
if (client) {
|
||||
try {
|
||||
// Wait for the client to connect with a timeout of 5000ms.
|
||||
const connectPromise = client.connect();
|
||||
const timeoutPromise = createTimeoutPromise(5000, "Redis connection timed out"); // 5000ms timeout
|
||||
await Promise.race([connectPromise, timeoutPromise]);
|
||||
} catch (error) {
|
||||
console.warn("Failed to connect Redis client:", error);
|
||||
|
||||
console.warn("Disconnecting the Redis client...");
|
||||
// Try to disconnect the client to stop it from reconnecting.
|
||||
client
|
||||
.disconnect()
|
||||
.then(() => {
|
||||
console.info("Redis client disconnected.");
|
||||
})
|
||||
.catch(() => {
|
||||
console.warn("Failed to quit the Redis client after failing to connect.");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {import("@neshca/cache-handler").Handler | null} */
|
||||
let handler;
|
||||
|
||||
if (client?.isReady) {
|
||||
const redisHandlerOptions = {
|
||||
client,
|
||||
keyPrefix: "fb:",
|
||||
timeoutMs: 1000,
|
||||
};
|
||||
|
||||
// Create the `redis-stack` Handler if the client is available and connected.
|
||||
handler = await createRedisHandler(redisHandlerOptions);
|
||||
} else {
|
||||
// Fallback to LRU handler if Redis client is not available.
|
||||
// The application will still work, but the cache will be in memory only and not shared.
|
||||
handler = createLruHandler();
|
||||
console.log("Using LRU handler for caching.");
|
||||
}
|
||||
|
||||
return {
|
||||
handlers: [handler],
|
||||
};
|
||||
});
|
||||
|
||||
const cacheHandler = new Next15CacheHandler();
|
||||
export default cacheHandler;
|
||||
@@ -16,7 +16,7 @@ const getHostname = (url) => {
|
||||
|
||||
const nextConfig = {
|
||||
assetPrefix: process.env.ASSET_PREFIX_URL || undefined,
|
||||
cacheHandler: require.resolve("./cache-handler.js"),
|
||||
cacheHandler: require.resolve("./cache-handler.mjs"),
|
||||
cacheMaxMemorySize: 0, // disable default in-memory caching
|
||||
output: "standalone",
|
||||
poweredByHeader: false,
|
||||
|
||||
Reference in New Issue
Block a user