fix(web): throttle workbench session list refresh pressure (#1914)
This commit is contained in:
@@ -27,8 +27,9 @@ const ACTIVE_TURN_GAP_MAX_DELAY_MS = 5_000;
|
||||
const SESSION_LIST_PAGE_LIMIT = 20;
|
||||
const WORKBENCH_READ_HYDRATION_CONCURRENCY = 3;
|
||||
const WORKBENCH_READ_FAILURE_COOLDOWN_MS = 5_000;
|
||||
const SESSION_LIST_REALTIME_REFRESH_DELAY_MS = 1_200;
|
||||
const SESSION_LIST_TERMINAL_REFRESH_DELAY_MS = 400;
|
||||
const SESSION_LIST_REALTIME_REFRESH_DELAY_MS = 5_000;
|
||||
const SESSION_LIST_TERMINAL_REFRESH_DELAY_MS = 1_500;
|
||||
const SESSION_LIST_MIN_REFRESH_INTERVAL_MS = 15_000;
|
||||
|
||||
interface HydrateOptions {
|
||||
sessionId?: string | null;
|
||||
@@ -80,6 +81,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
let activeTurnGapTimer: number | null = null;
|
||||
const sessionListRefreshInFlight = new Map<string, Promise<void>>();
|
||||
const sessionListRefreshTimers = new Map<string, number>();
|
||||
const sessionListLastRefreshAtByKey = new Map<string, number>();
|
||||
let workbenchReadHydrationActive = 0;
|
||||
const workbenchReadHydrationQueue: Array<() => void> = [];
|
||||
const workbenchReadCooldownUntilByKey = new Map<string, number>();
|
||||
@@ -239,7 +241,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
recordWorkbenchLoadingState({ scope: "session_detail", active: false, reason: "select_session", sessionId: selected.sessionId });
|
||||
recordWorkbenchLoadingState({ scope: "workbench", active: false, reason: "select_session", sessionId: selected.sessionId });
|
||||
error.value = null;
|
||||
await refreshSessions(selected.sessionId);
|
||||
await refreshSessions(selected.sessionId, { force: true });
|
||||
finishWorkbenchSessionSwitchFullLoad(selected.sessionId, "ok");
|
||||
return activeSessionId.value === selected.sessionId;
|
||||
}
|
||||
@@ -264,7 +266,7 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
return;
|
||||
}
|
||||
forgetSession(sessionId);
|
||||
await refreshSessions(null);
|
||||
await refreshSessions(null, { force: true });
|
||||
const next = sessions.value.find((session) => !isArchivedSession(session)) ?? null;
|
||||
replaceActiveSessionSelection(next?.sessionId ?? null);
|
||||
currentRequest.value = null;
|
||||
@@ -275,12 +277,16 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
restartRealtime("delete-current-session");
|
||||
}
|
||||
|
||||
async function refreshSessions(includeSessionId: string | null = activeSessionId.value): Promise<void> {
|
||||
async function refreshSessions(includeSessionId: string | null = activeSessionId.value, options: { force?: boolean } = {}): Promise<void> {
|
||||
const requestIncludeSessionId = firstNonEmptyString(includeSessionId);
|
||||
const requestLimit = currentSessionListLimit();
|
||||
const requestKey = sessionListRefreshKey(requestIncludeSessionId, requestLimit);
|
||||
const existing = sessionListRefreshInFlight.get(requestKey);
|
||||
if (existing) return existing;
|
||||
const now = Date.now();
|
||||
const lastRefreshAt = sessionListLastRefreshAtByKey.get(requestKey) ?? 0;
|
||||
if (options.force !== true && lastRefreshAt > 0 && now - lastRefreshAt < SESSION_LIST_MIN_REFRESH_INTERVAL_MS) return;
|
||||
sessionListLastRefreshAtByKey.set(requestKey, now);
|
||||
const refresh = refreshSessionsNow(requestIncludeSessionId, requestLimit).finally(() => {
|
||||
if (sessionListRefreshInFlight.get(requestKey) === refresh) sessionListRefreshInFlight.delete(requestKey);
|
||||
});
|
||||
@@ -315,10 +321,13 @@ export const useWorkbenchStore = defineStore("workbench", () => {
|
||||
}
|
||||
const existing = sessionListRefreshTimers.get(requestKey);
|
||||
if (existing) window.clearTimeout(existing);
|
||||
const lastRefreshAt = sessionListLastRefreshAtByKey.get(requestKey) ?? 0;
|
||||
const cooldownMs = lastRefreshAt > 0 ? Math.max(0, SESSION_LIST_MIN_REFRESH_INTERVAL_MS - (Date.now() - lastRefreshAt)) : 0;
|
||||
const boundedDelayMs = Math.max(0, Math.trunc(delayMs), cooldownMs);
|
||||
const timer = window.setTimeout(() => {
|
||||
sessionListRefreshTimers.delete(requestKey);
|
||||
void refreshSessions(requestIncludeSessionId);
|
||||
}, Math.max(0, Math.trunc(delayMs)));
|
||||
}, boundedDelayMs);
|
||||
sessionListRefreshTimers.set(requestKey, timer);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user