58 lines
2.3 KiB
TypeScript
58 lines
2.3 KiB
TypeScript
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;
|
|
}
|