Serialize refresh scheduling and remove overlap polling

This commit is contained in:
2026-02-07 01:47:36 +01:00
parent 78701cebf2
commit 5e84686678
2 changed files with 66 additions and 40 deletions

View File

@@ -30,8 +30,55 @@ import {
refreshPhaseData,
} from "./js/data.js";
initI18n();
const REFRESH_INTERVAL_MS = 4000;
let refreshInFlight = null;
let refreshTimerId = null;
let refreshSchedulerStarted = false;
async function runSerializedRefresh() {
if (refreshInFlight) return refreshInFlight;
refreshInFlight = refreshPhaseData().finally(() => {
refreshInFlight = null;
});
return refreshInFlight;
}
async function refreshWithUiErrorHandling() {
try {
await runSerializedRefresh();
} catch (err) {
if (!handleAuthError(err, clearUserState)) toast(err.message, true);
}
}
function scheduleNextRefresh() {
refreshTimerId = window.setTimeout(async () => {
if (!document.hidden) {
await refreshWithUiErrorHandling();
}
scheduleNextRefresh();
}, REFRESH_INTERVAL_MS);
}
function startRefreshScheduler() {
if (refreshSchedulerStarted) return;
refreshSchedulerStarted = true;
document.addEventListener("visibilitychange", () => {
if (!document.hidden) {
refreshWithUiErrorHandling();
}
});
if (refreshTimerId !== null) {
window.clearTimeout(refreshTimerId);
}
scheduleNextRefresh();
}
configureUiRuntime({
refreshPhaseData,
refreshPhaseData: runSerializedRefresh,
loadSuggestData,
loadVoteData,
handleAuthError: (err) => handleAuthError(err, clearUserState),
@@ -105,7 +152,7 @@ function setupHandlers() {
setSavedUsername(username);
state.isAuthenticated = true;
setAuthUI(true);
await refreshPhaseData();
await runSerializedRefresh();
toast(t("toast.loggedIn"));
} catch (err) {
if (err?.status === 401) return toast(t("auth.invalidCredentials"), true);
@@ -132,7 +179,7 @@ function setupHandlers() {
setSavedUsername(username);
state.isAuthenticated = true;
setAuthUI(true);
await refreshPhaseData();
await runSerializedRefresh();
toast(t("toast.registered"));
} catch (err) {
if (handleAuthError(err, clearUserState)) return;
@@ -214,7 +261,7 @@ function setupHandlers() {
}
renderPhasePill();
toast(t("admin.resultsUpdated"));
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
e.target.checked = !desired;
toast(err.message, true);
@@ -233,7 +280,7 @@ function setupHandlers() {
try {
await adminApi.linkSuggestions(source, target);
toast(t("admin.linkDone"));
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}
@@ -250,7 +297,7 @@ function setupHandlers() {
try {
await adminApi.grantJoker(playerId);
toast(t("admin.jokerGranted"));
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}
@@ -266,7 +313,7 @@ function setupHandlers() {
await adminApi.deletePlayer(playerId);
toast(t("admin.deleteDone"));
close();
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}
@@ -281,7 +328,7 @@ async function adminAction(fn, successMessage) {
try {
await fn();
toast(successMessage);
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}
@@ -289,16 +336,8 @@ async function adminAction(fn, successMessage) {
async function main() {
setupHandlers();
try {
await refreshPhaseData();
} catch (err) {
toast(err.message, true);
}
setInterval(() => {
refreshPhaseData().catch((err) => {
if (!handleAuthError(err, clearUserState)) toast(err.message, true);
});
}, 4000);
await refreshWithUiErrorHandling();
startRefreshScheduler();
}
main();
@@ -358,7 +397,7 @@ function bindNavButtons() {
state.resultsOpen = resp.resultsOpen ?? state.resultsOpen;
state.votesRendered = false;
renderPhasePill();
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}
@@ -376,7 +415,7 @@ function bindNavButtons() {
state.resultsOpen = resp.resultsOpen ?? state.resultsOpen;
state.votesRendered = false;
renderPhasePill();
await refreshPhaseData();
await runSerializedRefresh();
} catch (err) {
toast(err.message, true);
}