Ctrl K
ComunidadGuías…

instrumentation.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
/**
 * instrumentation.ts
 *
 * Next.js calls `register()` once per server process at boot. We use
 * it to warm up the zone poller so PDNS stats keep landing in the DB
 * even when nobody is logged in - otherwise the poller is lazy-started
 * by authenticated page renders / SSE subscribers and the dashboard
 * grew a gap whenever the app sat idle for hours.
 *
 * We MUST NOT directly import server-only modules here. `instrumentation.ts`
 * is bundled separately from regular route handlers and Next.js 15 ignores
 * `serverExternalPackages` for it (vercel/next.js#53523) - even a dynamic
 * `await import(...)` traces through `lib/db` to `pg` / `better-sqlite3` and
 * webpack chokes on their `require('fs'|'path'|'stream')` calls.
 *
 * Instead we fire a localhost fetch to `/healthz` once the HTTP server
 * is listening. The healthz handler is a normal Node-runtime route, so
 * it respects `serverExternalPackages` and can call `ensurePollerRunning()`
 * via the regular import graph. After that first hit Docker's own
 * healthcheck (every 15 s) keeps the poller's heartbeat fresh, so the
 * idle-shutdown timer never fires.
 */

export function register() {
  // Edge runtime can't fetch http://127.0.0.1 in the way we need and
  // doesn't run our route handlers anyway.
  if (process.env["NEXT_RUNTIME"] !== "nodejs") return;

  // Redis is the cross-replica coordination layer (ADR-0016): rate limiting,
  // realtime SSE fan-out, and reveal-once tokens go through it when set. When
  // unset everything runs in-process - correct for a single instance, but a
  // multi-replica deploy MUST set REDIS_URL (and share a Postgres DATABASE_URL)
  // or replicas won't share login throttling, SSE events, or reveal tokens.
  console.info(
    process.env["REDIS_URL"]
      ? "[startup] REDIS_URL set - rate limiting, realtime SSE fan-out, and reveal tokens are coordinated across replicas (HA-ready)."
      : "[startup] REDIS_URL not set - running single-instance (rate limiting, SSE fan-out, and reveal tokens are per-process). Set REDIS_URL + a shared Postgres for HA with >1 replica.",
  );

  // `register()` runs before the HTTP server is necessarily listening,
  // so we defer the kick by a short delay. Five seconds is generous -
  // Next.js typically binds within a second on cold boot. Fire-and-
  // forget: if it fails (server slower than expected), Docker's first
  // healthcheck will pick up the slack 30 s later.
  setTimeout(() => {
    const port = process.env["PORT"] ?? "3000";
    void fetch(`http://127.0.0.1:${port}/healthz`).catch(() => undefined);
  }, 5_000);
}