diff --git a/tools/cldr-apps/js/src/esm/cldrAnnounce.mjs b/tools/cldr-apps/js/src/esm/cldrAnnounce.mjs index a0c5dd68fa1..9b0bb9fb9dc 100644 --- a/tools/cldr-apps/js/src/esm/cldrAnnounce.mjs +++ b/tools/cldr-apps/js/src/esm/cldrAnnounce.mjs @@ -3,17 +3,25 @@ * The display logic is in AnnouncePanel.vue. */ import * as cldrAjax from "./cldrAjax.mjs"; +import * as cldrSchedule from "./cldrSchedule.mjs"; import * as cldrStatus from "./cldrStatus.mjs"; /** * This should be false for production. It can be made true during debugging, which - * may be useful for performance testing. Also, there is a bug where "announce" requests - * (as well as "completion" requests) are not only made too often (every 15 seconds synced - * with status requests), but are made in pairs where one "announce" request immediately follows - * another, see https://unicode-org.atlassian.net/browse/CLDR-16900 + * may be useful for performance testing. */ const DISABLE_ANNOUNCEMENTS = false; +const CLDR_ANNOUNCE_DEBUG = false; + +const ANNOUNCE_REFRESH_SECONDS = 60; // one minute + +const schedule = new cldrSchedule.FetchSchedule( + "cldrAnnounce", + ANNOUNCE_REFRESH_SECONDS, + CLDR_ANNOUNCE_DEBUG +); + let thePosts = null; let callbackSetData = null; @@ -28,6 +36,9 @@ async function refresh(viewCallbackSetData) { if (DISABLE_ANNOUNCEMENTS) { return; } + if (schedule.tooSoon()) { + return; + } if (!cldrStatus.getSurveyUser()) { if (viewCallbackSetData) { viewCallbackSetData(null); @@ -36,6 +47,7 @@ async function refresh(viewCallbackSetData) { } callbackSetData = viewCallbackSetData; const url = cldrAjax.makeApiUrl("announce", null); + schedule.setRequestTime(); return await cldrAjax .doFetch(url) .then(cldrAjax.handleFetchErrors) @@ -46,6 +58,7 @@ async function refresh(viewCallbackSetData) { function setPosts(json) { thePosts = json; + schedule.setResponseTime(); if (callbackSetData) { callbackSetData(thePosts); } diff --git a/tools/cldr-apps/js/src/esm/cldrProgress.mjs b/tools/cldr-apps/js/src/esm/cldrProgress.mjs index bb702419dff..76a62546963 100644 --- a/tools/cldr-apps/js/src/esm/cldrProgress.mjs +++ b/tools/cldr-apps/js/src/esm/cldrProgress.mjs @@ -7,6 +7,7 @@ import * as cldrAjax from "./cldrAjax.mjs"; import * as cldrCoverage from "./cldrCoverage.mjs"; import * as cldrGui from "./cldrGui.mjs"; import * as cldrNotify from "./cldrNotify.mjs"; +import * as cldrSchedule from "./cldrSchedule.mjs"; import * as cldrStatus from "./cldrStatus.mjs"; import * as cldrSurvey from "./cldrSurvey.mjs"; import * as cldrText from "./cldrText.mjs"; @@ -14,6 +15,10 @@ import * as cldrVue from "./cldrVue.mjs"; import ProgressMeters from "../views/ProgressMeters.vue"; +const CLDR_PROGRESS_DEBUG = false; + +const LOCALE_METER_REFRESH_SECONDS = 60; // one minute + let progressWrapper = null; let pageProgressStats = null; @@ -22,10 +27,11 @@ let localeProgressStats = null; let pageProgressRows = null; -let timeLastRequestedLocaleData = 0; -let timeLastReceivedLocaleData = 0; - -const LOCALE_METER_REFRESH_MS = 60 * 1000; +const schedule = new cldrSchedule.FetchSchedule( + "cldrProgress", + LOCALE_METER_REFRESH_SECONDS, + CLDR_PROGRESS_DEBUG +); class MeterData { /** @@ -361,18 +367,10 @@ function fetchLocaleData(unlessLoaded) { if (!locale || locale === "USER") { return; // no locale } - if ( - unlessLoaded && - localeProgressStats && - localeProgressStats.locale === locale - ) { + if (unlessLoaded && localeProgressStats?.locale === locale) { // LocaleMeter is already set - // Still refresh if it's been long enough since last request and last response - const now = Date.now(); - if ( - now < timeLastReceivedLocaleData + LOCALE_METER_REFRESH_MS && - now < timeLastRequestedLocaleData + LOCALE_METER_REFRESH_MS - ) { + // Only refresh if it's been long enough since last request and last response + if (schedule.tooSoon()) { return; } } @@ -381,7 +379,7 @@ function fetchLocaleData(unlessLoaded) { } function reallyFetchLocaleData(locale) { - timeLastRequestedLocaleData = Date.now(); + schedule.setRequestTime(); const url = `api/completion/locale/${locale}`; cldrAjax .doFetch(url) @@ -394,9 +392,9 @@ function reallyFetchLocaleData(locale) { }) .then((data) => data.json()) .then((json) => { + schedule.setResponseTime(); progressWrapper.setHidden(false); setLocaleProgressStatsFromJson(json, locale); - timeLastReceivedLocaleData = Date.now(); refreshLocaleMeter(); }) .catch((err) => { diff --git a/tools/cldr-apps/js/src/esm/cldrSchedule.mjs b/tools/cldr-apps/js/src/esm/cldrSchedule.mjs new file mode 100644 index 00000000000..4d0d4c4a9b6 --- /dev/null +++ b/tools/cldr-apps/js/src/esm/cldrSchedule.mjs @@ -0,0 +1,67 @@ +/* + * cldrSchedule: for Survey Tool scheduling of http requests. + */ + +export class FetchSchedule { + /** + * Construct a new FetchSchedule object + * + * @param {String} description description or name of caller + * @param {Number} refreshSeconds postpone requests until this many seconds have elapsed since last request/response + * @param {Boolean} debug whether to log debugging info to console + * @returns the new FetchSchedule object + */ + constructor(description, refreshSeconds, debug) { + this.description = description; + this.refreshMillis = refreshSeconds * 1000; + this.debug = debug; + this.lastRequestTime = this.lastResponseTime = 0; + } + + setRequestTime() { + this.lastRequestTime = Date.now(); + if (this.debug) { + console.log( + this.description + " set lastRequestTime = " + this.lastRequestTime + ); + } + } + + setResponseTime() { + this.lastResponseTime = Date.now(); + if (this.debug) { + console.log( + this.description + " set lastResponseTime = " + this.lastResponseTime + ); + } + } + + /** + * Is it too soon to make a request? + * + * @returns true if it is too soon, else false + */ + tooSoon() { + const now = Date.now(); + if ( + now < this.lastResponseTime + this.refreshMillis || + now < this.lastRequestTime + this.refreshMillis + ) { + if (this.debug) { + console.log( + this.description + + " postponing request: less than " + + this.refreshMillis / 1000 + + " seconds elapsed; now = " + + now + ); + } + return true; + } else { + if (this.debug) { + console.log(this.description + " will make a request; now = " + now); + } + return false; + } + } +}