import { createScopedLogger } from "./utils/logger.server"; import { subscribeSubscriptionCache } from "./utils/services/.server/subscriptionCache.server"; import { subscribeTenantCache } from "./utils/db/tenant-cache.server"; import { subscribeFeatureFlagCache } from "./utils/services/.server/featureFlagCache.server"; import { wireTenantPlanLookup } from "./utils/services/.server/tenantPlanLookup.server"; const log = createScopedLogger("cache-bootstrap"); let started = false; function pubsubEnabled(): boolean { const raw = process.env.CACHE_INVALIDATION_ENABLED; if (raw === undefined || raw === null || raw === "") return true; return raw.toLowerCase() !== "false" && raw !== "0"; } /** * Idempotent boot hook. Starts every cache-invalidation subscriber this * web replica needs to keep its in-process L1 caches consistent with the * SharedStore L2 (and with mutations originating in other apps such as * the Stripe webhook in apps/api). * * Safe to call multiple times — only the first invocation wires the * subscribers; subsequent calls are no-ops. Failures are logged but * intentionally swallowed: the L1 cache TTL is the safety net. */ export function startCacheSubscribers(): void { if (started) return; started = true; // Wire the BullMQ tenant-plan lookup unconditionally — it reads from the // subscription cache which still serves locally when pub/sub is off. wireTenantPlanLookup(); if (!pubsubEnabled()) { log.warn( { component: "cache-bootstrap" }, "CACHE_INVALIDATION_ENABLED=false — pub/sub subscribers will not start (L1 TTL is the only consistency mechanism)", ); return; } void Promise.all([ subscribeSubscriptionCache().catch((err: unknown) => { log.error({ err }, "subscription cache subscriber failed to start"); }), subscribeTenantCache().catch((err: unknown) => { log.error({ err }, "tenant cache subscriber failed to start"); }), subscribeFeatureFlagCache().catch((err: unknown) => { log.error({ err }, "feature-flag cache subscriber failed to start"); }), ]).then(() => { log.info({ component: "cache-bootstrap" }, "cache subscribers started"); }); } /** Test seam: reset the started flag. */ export function __resetCacheBootstrapForTests(): void { started = false; }