fix(catalog) : retry transient storage quorum failures

This commit is contained in:
2026-10-12 19:53:19 +07:00 Unverified
parent 3fb34ffde2
commit fae9e146e1
3 changed files with 73 additions and 16 deletions
+1 -16
View File
@@ -35,6 +35,7 @@ import type {
} from "@/lib/catalog/lunaris";
import { customTravelers, isUpstreamTraveler } from "@/lib/catalog/travelers";
import { withCatalogSyncLock } from "@/lib/catalog/sync-lock";
import { retryTransient } from "@/lib/catalog/sync-retry";
import { getRedisClient, redisEventPrefix } from "@/lib/redis/client";
import {
catalogFormatVersion,
@@ -128,22 +129,6 @@ interface SyncedCharacter {
type SyncControl = { signal?: AbortSignal; checkCancelled: () => Promise<void>; report: (phase: string, completed: number, total: number, message: string) => Promise<void> };
async function retryTransient<T>(label: string, task: () => Promise<T>, signal?: AbortSignal): Promise<T> {
for (let attempt = 1; ; attempt += 1) {
signal?.throwIfAborted();
try {
return await task();
} catch (cause) {
signal?.throwIfAborted();
const message = cause instanceof Error ? cause.message : String(cause);
if (attempt >= 3 || !/timed out|timeout|unexpected error has occurred/i.test(message)) {
throw new Error(`${label}: ${message}`, { cause });
}
await new Promise((resolve) => setTimeout(resolve, attempt * 1_000));
}
}
}
async function getJson(url: string, signal?: AbortSignal): Promise<unknown> {
return retryTransient(`Lunaris request ${url}`, async () => {
const response = await fetch(url, {