contents/ui/CostRefreshPolicy.js
.pragma library
var automaticRefreshIntervalMs = 60 * 60 * 1000
// The controller's repeating timer is not aligned with the last attempt, so
// it checks every minute and this policy decides when the hour has elapsed.
// Checking only hourly lands just short of the cooldown and skips an hour.
var automaticRefreshCheckIntervalMs = 60 * 1000
var clearAction = "clear"
var keepAction = "keep"
var startAction = "start"
function padDayPart(value) {
return (value < 10 ? "0" : "") + String(value)
}
// Local calendar bucket for spend history. Day changes (including timezone
// shifts that move the local date) make yesterday's snapshot stale even when
// the hourly attempt cooldown has not elapsed. Returns "" for unusable input.
function bucketDayForMs(nowMs) {
var now = Number(nowMs)
if (!isFinite(now) || now < 0) {
return ""
}
var date = new Date(now)
if (isNaN(date.getTime())) {
return ""
}
return date.getFullYear() + "-" + padDayPart(date.getMonth() + 1)
+ "-" + padDayPart(date.getDate())
}
// True only when two valid timestamps fall on different local days with a
// forward clock. Rollbacks and invalid input stay false: the hourly baseline
// already restarts on rollback, and invalid clocks keep the current state.
function isNewBucketDay(lastAttemptAtMs, nowMs) {
var previous = Number(lastAttemptAtMs)
var now = Number(nowMs)
if (!isFinite(previous) || previous < 0 || !isFinite(now) || now < 0
|| now < previous) {
return false
}
var previousDay = bucketDayForMs(previous)
var currentDay = bucketDayForMs(now)
return previousDay.length > 0 && currentDay.length > 0
&& previousDay !== currentDay
}
function refreshAction(commandAvailable, loading, forced, lastAttemptAtMs, nowMs) {
if (commandAvailable !== true) {
return clearAction
}
if (forced === true) {
return startAction
}
if (loading === true) {
return keepAction
}
var now = Number(nowMs)
if (!isFinite(now) || now < 0) {
return keepAction
}
var previous = Number(lastAttemptAtMs)
if (typeof lastAttemptAtMs !== "number" || !isFinite(previous)
|| previous < 0 || now < previous) {
return startAction
}
// A calendar-day change makes the snapshot stale even within the hour.
// Loading already returned keep above, so an active scan is never replaced.
if (isNewBucketDay(previous, now)) {
return startAction
}
return now - previous >= automaticRefreshIntervalMs ? startAction : keepAction
}