From 498d781e19223a0def8c22e73e9a7075539fdf49 Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Fri, 14 Aug 2026 20:16:34 +0200 Subject: [PATCH] fix: isolate node instrumentation --- apps/nextjs/src/instrumentation-node.ts | 35 +++++++++++++++++++++++++ apps/nextjs/src/instrumentation.ts | 35 ++----------------------- 2 files changed, 37 insertions(+), 33 deletions(-) create mode 100644 apps/nextjs/src/instrumentation-node.ts diff --git a/apps/nextjs/src/instrumentation-node.ts b/apps/nextjs/src/instrumentation-node.ts new file mode 100644 index 000000000..68d81af8d --- /dev/null +++ b/apps/nextjs/src/instrumentation-node.ts @@ -0,0 +1,35 @@ +export async function registerNodeInstrumentation() { + const { createLogger } = await import("@homarr/core/infrastructure/logs"); + const logger = createLogger({ module: "instrumentation" }); + + const startTasksAsync = async () => { + try { + const tasks = await import("@homarr/tasks"); + // Cron run-on-start hooks can perform slow external work. Keep dashboard + // readiness independent, but never leave the process permanently degraded. + void tasks.startupPromise.catch((cause: unknown) => { + logger.error(new Error("Failed to start embedded tasks service", { cause })); + process.exit(1); + }); + } catch (cause) { + const error = new Error("Failed to load embedded tasks service", { cause }); + logger.error(error); + throw error; + } + }; + + const startWebsocketAsync = async () => { + try { + const websocket = await import("@homarr/websocket"); + // Listening is a bounded local readiness condition and prevents Next from + // becoming healthy with subscriptions unavailable. + await websocket.startupPromise; + } catch (cause) { + const error = new Error("Failed to start embedded websocket service", { cause }); + logger.error(error); + throw error; + } + }; + + await Promise.all([startTasksAsync(), startWebsocketAsync()]); +} diff --git a/apps/nextjs/src/instrumentation.ts b/apps/nextjs/src/instrumentation.ts index e1755a1b4..bfe15bdbf 100644 --- a/apps/nextjs/src/instrumentation.ts +++ b/apps/nextjs/src/instrumentation.ts @@ -2,37 +2,6 @@ export async function register() { if (process.env.NEXT_RUNTIME !== "nodejs") return; if (process.env.NODE_ENV !== "production") return; - const { createLogger } = await import("@homarr/core/infrastructure/logs"); - const logger = createLogger({ module: "instrumentation" }); - - const startTasksAsync = async () => { - try { - const tasks = await import("@homarr/tasks"); - // Cron run-on-start hooks can perform slow external work. Keep dashboard - // readiness independent, but never leave the process permanently degraded. - void tasks.startupPromise.catch((cause: unknown) => { - logger.error(new Error("Failed to start embedded tasks service", { cause })); - process.exit(1); - }); - } catch (cause) { - const error = new Error("Failed to load embedded tasks service", { cause }); - logger.error(error); - throw error; - } - }; - - const startWebsocketAsync = async () => { - try { - const websocket = await import("@homarr/websocket"); - // Listening is a bounded local readiness condition and prevents Next from - // becoming healthy with subscriptions unavailable. - await websocket.startupPromise; - } catch (cause) { - const error = new Error("Failed to start embedded websocket service", { cause }); - logger.error(error); - throw error; - } - }; - - await Promise.all([startTasksAsync(), startWebsocketAsync()]); + const { registerNodeInstrumentation } = await import("./instrumentation-node"); + await registerNodeInstrumentation(); }