Retry the initial boot using p-retry

This commit is contained in:
Matt Aitken
2026-04-16 14:02:43 +01:00
parent 3073289513
commit 0f94684610
2 changed files with 26 additions and 3 deletions
@@ -13,7 +13,12 @@ export class OrganizationDataStoresRegistry {
private _loaded = false;
private _readyResolve!: () => void;
/** Resolves once the initial `loadFromDatabase()` completes successfully. */
/**
* Resolves once the initial `loadFromDatabase()` completes successfully.
* At process startup the singleton loads the registry with unbounded retries
* (exponential backoff, capped delay) until Postgres is reachable; until then
* this promise stays pending and callers that await readiness will block.
*/
readonly isReady: Promise<void>;
constructor(prisma: PrismaClient | PrismaReplicaClient) {
@@ -1,5 +1,7 @@
import pRetry from "p-retry";
import { $replica } from "~/db.server";
import { env } from "~/env.server";
import { logger } from "~/services/logger.server";
import { signalsEmitter } from "~/services/signals.server";
import { singleton } from "~/utils/singleton";
import { OrganizationDataStoresRegistry } from "./organizationDataStoresRegistry.server";
@@ -7,8 +9,24 @@ import { OrganizationDataStoresRegistry } from "./organizationDataStoresRegistry
export const organizationDataStoresRegistry = singleton("organizationDataStoresRegistry", () => {
const registry = new OrganizationDataStoresRegistry($replica);
registry.loadFromDatabase().catch((err) => {
console.error("[OrganizationDataStoresRegistry] Failed to initialize", err);
// Runs as soon as this singleton is created (first import of this module). The
// registrys `isReady` promise resolves when this eventually succeeds.
const startupLoadPromise = pRetry(() => registry.loadFromDatabase(), {
forever: true,
retries: 10,
minTimeout: 1_000,
maxTimeout: 60_000,
factor: 2,
onFailedAttempt: (error) => {
logger.warn("[OrganizationDataStoresRegistry] Startup load failed, retrying", {
attemptNumber: error.attemptNumber,
retriesLeft: error.retriesLeft,
error: error.message,
});
},
});
startupLoadPromise.catch((err) => {
console.error("[OrganizationDataStoresRegistry] Unexpected startup load failure", err);
});
const interval = setInterval(() => {