Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/.env.development
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ DATACITE_PASSWORD=""
DATACITE_API_URL="https://api.test.datacite.org"

GCLOUD_KEY_FILE='xxx'
VALKEY_URL='redis://localhost:6379'
VALKEY_URL='redis://cache:6379'
95 changes: 9 additions & 86 deletions core/cache-handler.mjs
Original file line number Diff line number Diff line change
@@ -1,88 +1,11 @@
// Based on https://github.com/fortedigital/nextjs-cache-handler#full-example
/**
* Solution taken from here: https://github.com/vercel/next.js/discussions/48324#discussioncomment-10542097
*
* We are reexporting `next.js`'s default cache handler to get around
* the fixed 2mb limit for cached fetches.
* We run into this limit somewhat quickly if we fetch more than 100 pubs.
*/

import { PHASE_PRODUCTION_BUILD } from "next/constants.js";
import createBufferStringHandler from "@fortedigital/nextjs-cache-handler/buffer-string-decorator";
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";
import FileSystemCache from "next/dist/server/lib/incremental-cache/file-system-cache.js";

// 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;
}

// Main promise initializing the handler
global.cacheHandlerConfigPromise = (async () => {
/** @type {import("redis").RedisClientType | null} */
let redisClient = null;
if (PHASE_PRODUCTION_BUILD !== process.env.NEXT_PHASE) {
try {
redisClient = createClient({
url: process.env.VALKEY_URL,
pingInterval: 10000,
});
redisClient.on("error", (e) => {
if (typeof process.env.NEXT_PRIVATE_DEBUG_CACHE !== "undefined") {
console.warn("Redis error", e);
}
global.cacheHandlerConfig = null;
global.cacheHandlerConfigPromise = null;
});
} catch (error) {
console.warn("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.warn("Failed to connect Redis client:", error);
await redisClient
.disconnect()
.catch(() =>
console.warn("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:",
keyExpirationStrategy: "EXAT",
});

global.cacheHandlerConfigPromise = null;

global.cacheHandlerConfig = {
handlers: [createBufferStringHandler(redisCacheHandler)],
};

return global.cacheHandlerConfig;
})();

return global.cacheHandlerConfigPromise;
});

export default new Next15CacheHandler();
export default FileSystemCache;
5 changes: 0 additions & 5 deletions core/instrumentation.node.mts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ if (env.NODE_ENV === "production") {

// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
integrations: [
Sentry.redisIntegration({
cachePrefixes: ["nextjs:"],
}),
],
});
logger.info("✅ Successfully instrumented Sentry");
}
Expand Down
3 changes: 0 additions & 3 deletions core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,11 @@
"@dnd-kit/sortable": "^8.0.0",
"@dnd-kit/utilities": "^3.2.2",
"@faker-js/faker": "^9.0.0",
"@fortedigital/nextjs-cache-handler": "^1.2.0",
"@googleapis/drive": "^8.16.0",
"@handlewithcare/react-prosemirror": "catalog:",
"@honeycombio/opentelemetry-node": "catalog:",
"@hookform/resolvers": "catalog:",
"@icons-pack/react-simple-icons": "^10.2.0",
"@neshca/cache-handler": "^1.9.0",
"@nimpl/getters": "^2.0.0",
"@node-rs/argon2": "^1.8.3",
"@opentelemetry/auto-instrumentations-node": "catalog:",
Expand Down Expand Up @@ -127,7 +125,6 @@
"react-hook-form": "catalog:",
"react-markdown": "^9.0.1",
"reactflow": "^11.10.4",
"redis": "^4.7.0",
"rehype": "^13.0.2",
"rehype-format": "^5.0.0",
"rehype-parse": "^9.0.1",
Expand Down
2 changes: 0 additions & 2 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ services:
service: cache
networks:
- app-network
ports:
- 6379:6379

minio-init:
env_file:
Expand Down
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
"dev:inbucket:stop": "docker compose -f docker-compose.dev.yml down inbucket",
"dev:minio:start": "docker compose -f docker-compose.dev.yml up minio -d && docker compose -f docker-compose.dev.yml run minio-init",
"dev:minio:stop": "docker compose -f docker-compose.dev.yml down minio",
"dev:cache:start": "docker compose -f docker-compose.dev.yml up cache -d",
"dev:cache:stop": "docker compose -f docker-compose.dev.yml down cache",
"dev:setup": "pnpm install && docker compose -f docker-compose.dev.yml up -d && pnpm p:dev && pnpm --filter core migrate-dev && pnpm --filter core reset",
"dev:teardown": "docker compose -f docker-compose.dev.yml down -v",
"integration:setup": "docker compose -f docker-compose.test.yml --profile integration up -d",
Expand Down
Loading
Loading