- Move blocking usage queries and core lifecycle operations to background workers, limit concurrency, and prevent overlapping core operations - Coalesce statistics refreshes and consolidate category aggregations, reducing unfiltered analysis queries from 11 to 4 - Cache bundled model prices, reuse management API connections, and reduce redundant checks in the usage collector - Throttle download progress and guide positioning updates, and avoid redundant renders when core status is unchanged - Bound and coalesce configuration watcher events, and reuse a single model catalog refresh worker - Stop scheduling remaining health checks when the dialog closes and limit backend health-check concurrency - Replace overlapping OAuth polling with sequential requests, retry backoff, timeouts, and stale callback protection - Add regression tests and a statistics benchmark script, and move performance verification documentation to agent_docs
67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
export function createRefreshScheduler(minIntervalMs = 1_000) {
|
|
type Task = () => Promise<void>;
|
|
type Completion = { promise: Promise<void>; resolve: () => void; reject: (error: unknown) => void };
|
|
let running = false;
|
|
let completedAt = -Infinity;
|
|
let pending: Task | null = null;
|
|
let urgent = false;
|
|
let completion: Completion | null = null;
|
|
let timer: ReturnType<typeof setTimeout> | null = null;
|
|
|
|
const pump = () => {
|
|
if (running || !pending) return;
|
|
if (timer !== null) clearTimeout(timer);
|
|
timer = null;
|
|
const delay = urgent ? 0 : Math.max(0, minIntervalMs - (performance.now() - completedAt));
|
|
if (delay > 0) {
|
|
timer = setTimeout(pump, delay);
|
|
return;
|
|
}
|
|
const task = pending;
|
|
const currentCompletion = completion!;
|
|
pending = null;
|
|
completion = null;
|
|
urgent = false;
|
|
running = true;
|
|
void (async () => {
|
|
try {
|
|
await task();
|
|
currentCompletion.resolve();
|
|
} catch (error) {
|
|
currentCompletion.reject(error);
|
|
} finally {
|
|
running = false;
|
|
completedAt = performance.now();
|
|
pump();
|
|
}
|
|
})();
|
|
};
|
|
|
|
return {
|
|
schedule(task: Task, immediate = false): Promise<void> {
|
|
pending = task;
|
|
urgent ||= immediate;
|
|
if (!completion) {
|
|
let resolve!: () => void;
|
|
let reject!: (error: unknown) => void;
|
|
const promise = new Promise<void>((onResolved, onRejected) => {
|
|
resolve = onResolved;
|
|
reject = onRejected;
|
|
});
|
|
completion = { promise, resolve, reject };
|
|
}
|
|
const result = completion.promise;
|
|
pump();
|
|
return result;
|
|
},
|
|
cancelPending() {
|
|
if (timer !== null) clearTimeout(timer);
|
|
timer = null;
|
|
pending = null;
|
|
urgent = false;
|
|
completion?.resolve();
|
|
completion = null;
|
|
},
|
|
};
|
|
}
|