perf(web): queue dashboard tile hydration
This commit is contained in:
parent
83c2c0f4a4
commit
fd0559a143
4 changed files with 194 additions and 6 deletions
|
|
@ -88,3 +88,60 @@ export function attachDashboardRefreshLifecycle(
|
|||
options.windowTarget.removeEventListener("pagehide", handlePageHide);
|
||||
};
|
||||
}
|
||||
|
||||
export interface DashboardHydrationQueueOptions<TItem> {
|
||||
concurrency: number;
|
||||
hydrate: (item: TItem) => Promise<void> | void;
|
||||
items: TItem[];
|
||||
signal: AbortSignal;
|
||||
}
|
||||
|
||||
export async function runDashboardHydrationQueue<TItem>(
|
||||
options: DashboardHydrationQueueOptions<TItem>,
|
||||
): Promise<void> {
|
||||
const concurrency = Math.max(1, Math.floor(options.concurrency));
|
||||
let nextIndex = 0;
|
||||
|
||||
async function worker() {
|
||||
while (!options.signal.aborted) {
|
||||
const item = options.items[nextIndex];
|
||||
nextIndex += 1;
|
||||
if (item === undefined) return;
|
||||
|
||||
await options.hydrate(item);
|
||||
}
|
||||
}
|
||||
|
||||
const workerCount = Math.min(concurrency, options.items.length);
|
||||
await Promise.all(
|
||||
Array.from({ length: workerCount }, () => worker()),
|
||||
);
|
||||
}
|
||||
|
||||
const dashboardTileBackoffDelaysMs = [15_000, 30_000, 60_000, 120_000];
|
||||
|
||||
export function createDashboardTileBackoff() {
|
||||
const failures = new Map<string, { attempts: number; nextAttemptAt: number }>();
|
||||
|
||||
return {
|
||||
canAttempt(key: string, now = Date.now()): boolean {
|
||||
const failure = failures.get(key);
|
||||
return !failure || now >= failure.nextAttemptAt;
|
||||
},
|
||||
recordFailure(key: string, now = Date.now()): void {
|
||||
const previousAttempts = failures.get(key)?.attempts || 0;
|
||||
const attempts = previousAttempts + 1;
|
||||
const delay =
|
||||
dashboardTileBackoffDelaysMs[
|
||||
Math.min(attempts - 1, dashboardTileBackoffDelaysMs.length - 1)
|
||||
];
|
||||
failures.set(key, {
|
||||
attempts,
|
||||
nextAttemptAt: now + delay,
|
||||
});
|
||||
},
|
||||
recordSuccess(key: string): void {
|
||||
failures.delete(key);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue