Skip to content

Commit c5f7ca3

Browse files
committed
Retry the initial boot using p-retry
1 parent 3d4538b commit c5f7ca3

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

apps/webapp/app/services/dataStores/organizationDataStoresRegistry.server.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,12 @@ export class OrganizationDataStoresRegistry {
1313
private _loaded = false;
1414
private _readyResolve!: () => void;
1515

16-
/** Resolves once the initial `loadFromDatabase()` completes successfully. */
16+
/**
17+
* Resolves once the initial `loadFromDatabase()` completes successfully.
18+
* At process startup the singleton loads the registry with unbounded retries
19+
* (exponential backoff, capped delay) until Postgres is reachable; until then
20+
* this promise stays pending and callers that await readiness will block.
21+
*/
1722
readonly isReady: Promise<void>;
1823

1924
constructor(prisma: PrismaClient | PrismaReplicaClient) {

apps/webapp/app/services/dataStores/organizationDataStoresRegistryInstance.server.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,32 @@
1+
import pRetry from "p-retry";
12
import { $replica } from "~/db.server";
23
import { env } from "~/env.server";
4+
import { logger } from "~/services/logger.server";
35
import { signalsEmitter } from "~/services/signals.server";
46
import { singleton } from "~/utils/singleton";
57
import { OrganizationDataStoresRegistry } from "./organizationDataStoresRegistry.server";
68

79
export const organizationDataStoresRegistry = singleton("organizationDataStoresRegistry", () => {
810
const registry = new OrganizationDataStoresRegistry($replica);
911

10-
registry.loadFromDatabase().catch((err) => {
11-
console.error("[OrganizationDataStoresRegistry] Failed to initialize", err);
12+
// Runs as soon as this singleton is created (first import of this module). The
13+
// registry’s `isReady` promise resolves when this eventually succeeds.
14+
const startupLoadPromise = pRetry(() => registry.loadFromDatabase(), {
15+
forever: true,
16+
retries: 10,
17+
minTimeout: 1_000,
18+
maxTimeout: 60_000,
19+
factor: 2,
20+
onFailedAttempt: (error) => {
21+
logger.warn("[OrganizationDataStoresRegistry] Startup load failed, retrying", {
22+
attemptNumber: error.attemptNumber,
23+
retriesLeft: error.retriesLeft,
24+
error: error.message,
25+
});
26+
},
27+
});
28+
startupLoadPromise.catch((err) => {
29+
console.error("[OrganizationDataStoresRegistry] Unexpected startup load failure", err);
1230
});
1331

1432
const interval = setInterval(() => {

0 commit comments

Comments
 (0)