Skip to content

Commit

Permalink
CLDR-16900 Limit frequency of announce and completion requests (#3583)
Browse files Browse the repository at this point in the history
  • Loading branch information
btangmu authored Mar 29, 2024
1 parent f117648 commit 8833c52
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 21 deletions.
21 changes: 17 additions & 4 deletions tools/cldr-apps/js/src/esm/cldrAnnounce.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -28,6 +36,9 @@ async function refresh(viewCallbackSetData) {
if (DISABLE_ANNOUNCEMENTS) {
return;
}
if (schedule.tooSoon()) {
return;
}
if (!cldrStatus.getSurveyUser()) {
if (viewCallbackSetData) {
viewCallbackSetData(null);
Expand All @@ -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)
Expand All @@ -46,6 +58,7 @@ async function refresh(viewCallbackSetData) {

function setPosts(json) {
thePosts = json;
schedule.setResponseTime();
if (callbackSetData) {
callbackSetData(thePosts);
}
Expand Down
32 changes: 15 additions & 17 deletions tools/cldr-apps/js/src/esm/cldrProgress.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,18 @@ 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";
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;
Expand All @@ -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 {
/**
Expand Down Expand Up @@ -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;
}
}
Expand All @@ -381,7 +379,7 @@ function fetchLocaleData(unlessLoaded) {
}

function reallyFetchLocaleData(locale) {
timeLastRequestedLocaleData = Date.now();
schedule.setRequestTime();
const url = `api/completion/locale/${locale}`;
cldrAjax
.doFetch(url)
Expand All @@ -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) => {
Expand Down
67 changes: 67 additions & 0 deletions tools/cldr-apps/js/src/esm/cldrSchedule.mjs
Original file line number Diff line number Diff line change
@@ -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;
}
}
}

0 comments on commit 8833c52

Please sign in to comment.