зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1140037 - Fix ping fuzzing calculations. r=dexter
This commit is contained in:
Родитель
0fe5bd8ea4
Коммит
3bf1f269c9
|
@ -22,6 +22,7 @@ Cu.import("resource://gre/modules/Task.jsm", this);
|
|||
Cu.import("resource://gre/modules/DeferredTask.jsm", this);
|
||||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Timer.jsm");
|
||||
Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
|
||||
|
||||
const LOGGER_NAME = "Toolkit.Telemetry";
|
||||
const LOGGER_PREFIX = "TelemetryController::";
|
||||
|
@ -55,6 +56,8 @@ const PING_SUBMIT_TIMEOUT_MS = 2 * 60 * 1000;
|
|||
|
||||
// We treat pings before midnight as happening "at midnight" with this tolerance.
|
||||
const MIDNIGHT_TOLERANCE_MS = 15 * 60 * 1000;
|
||||
// For midnight fuzzing we want to affect pings around midnight with this tolerance.
|
||||
const MIDNIGHT_TOLERANCE_FUZZ_MS = 5 * 60 * 1000;
|
||||
// We try to spread "midnight" pings out over this interval.
|
||||
const MIDNIGHT_FUZZING_INTERVAL_MS = 60 * 60 * 1000;
|
||||
const MIDNIGHT_FUZZING_DELAY_MS = Math.random() * MIDNIGHT_FUZZING_INTERVAL_MS;
|
||||
|
@ -126,16 +129,6 @@ function isNewPingFormat(aPing) {
|
|||
("version" in aPing) && (aPing.version >= 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Takes a date and returns it trunctated to a date with daily precision.
|
||||
*/
|
||||
function truncateToDays(date) {
|
||||
return new Date(date.getFullYear(),
|
||||
date.getMonth(),
|
||||
date.getDate(),
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
|
||||
function tomorrow(date) {
|
||||
let d = new Date(date);
|
||||
d.setDate(d.getDate() + 1);
|
||||
|
@ -506,17 +499,20 @@ let Impl = {
|
|||
* @return Number The next time (ms from UNIX epoch) when we can send pings.
|
||||
*/
|
||||
_getNextPingSendTime: function(now) {
|
||||
const todayDate = truncateToDays(now);
|
||||
const tomorrowDate = tomorrow(todayDate);
|
||||
const nextMidnightRangeStart = tomorrowDate.getTime() - MIDNIGHT_TOLERANCE_MS;
|
||||
const currentMidnightRangeEnd = todayDate.getTime() - MIDNIGHT_TOLERANCE_MS + Policy.midnightPingFuzzingDelay();
|
||||
const midnight = TelemetryUtils.getNearestMidnight(now, MIDNIGHT_FUZZING_INTERVAL_MS);
|
||||
|
||||
if (now.getTime() < currentMidnightRangeEnd) {
|
||||
return currentMidnightRangeEnd;
|
||||
// Don't delay ping if we are not close to midnight.
|
||||
if (!midnight) {
|
||||
return now.getTime();
|
||||
}
|
||||
|
||||
if (now.getTime() >= nextMidnightRangeStart) {
|
||||
return nextMidnightRangeStart + Policy.midnightPingFuzzingDelay();
|
||||
// Delay ping send if we are within the midnight fuzzing range.
|
||||
// This is from: |midnight - MIDNIGHT_TOLERANCE_FUZZ_MS|
|
||||
// to: |midnight + MIDNIGHT_FUZZING_INTERVAL_MS|
|
||||
const midnightRangeStart = midnight.getTime() - MIDNIGHT_TOLERANCE_FUZZ_MS;
|
||||
if (now.getTime() >= midnightRangeStart) {
|
||||
// We spread those ping sends out between |midnight| and |midnight + midnightPingFuzzingDelay|.
|
||||
return midnight.getTime() + Policy.midnightPingFuzzingDelay();
|
||||
}
|
||||
|
||||
return now.getTime();
|
||||
|
|
|
@ -20,6 +20,7 @@ Cu.import("resource://gre/modules/DeferredTask.jsm", this);
|
|||
Cu.import("resource://gre/modules/Preferences.jsm");
|
||||
Cu.import("resource://gre/modules/Task.jsm");
|
||||
Cu.import("resource://gre/modules/Timer.jsm");
|
||||
Cu.import("resource://gre/modules/TelemetryUtils.jsm", this);
|
||||
|
||||
const myScope = this;
|
||||
|
||||
|
@ -174,58 +175,6 @@ let Policy = {
|
|||
clearSchedulerTickTimeout: id => clearTimeout(id),
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a date and returns it trunctated to a date with daily precision.
|
||||
*/
|
||||
function truncateToDays(date) {
|
||||
return new Date(date.getFullYear(),
|
||||
date.getMonth(),
|
||||
date.getDate(),
|
||||
0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the difference between the times is within the provided tolerance.
|
||||
* @param {Number} t1 A time in milliseconds.
|
||||
* @param {Number} t2 A time in milliseconds.
|
||||
* @param {Number} tolerance The tolerance, in milliseconds.
|
||||
* @return {Boolean} True if the absolute time difference is within the tolerance, false
|
||||
* otherwise.
|
||||
*/
|
||||
function areTimesClose(t1, t2, tolerance) {
|
||||
return Math.abs(t1 - t2) <= tolerance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the next midnight for a date.
|
||||
* @param {Object} date The date object to check.
|
||||
* @return {Object} The Date object representing the next midnight.
|
||||
*/
|
||||
function getNextMidnight(date) {
|
||||
let nextMidnight = new Date(truncateToDays(date));
|
||||
nextMidnight.setDate(nextMidnight.getDate() + 1);
|
||||
return nextMidnight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the midnight which is closer to the provided date.
|
||||
* @param {Object} date The date object to check.
|
||||
* @return {Object} The Date object representing the closes midnight, or null if midnight
|
||||
* is not within the midnight tolerance.
|
||||
*/
|
||||
function getNearestMidnight(date) {
|
||||
let lastMidnight = truncateToDays(date);
|
||||
if (areTimesClose(date.getTime(), lastMidnight.getTime(), SCHEDULER_MIDNIGHT_TOLERANCE_MS)) {
|
||||
return lastMidnight;
|
||||
}
|
||||
|
||||
const nextMidnightDate = getNextMidnight(date);
|
||||
if (areTimesClose(date.getTime(), nextMidnightDate.getTime(), SCHEDULER_MIDNIGHT_TOLERANCE_MS)) {
|
||||
return nextMidnightDate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the ping type based on the payload.
|
||||
* @param {Object} aPayload The ping payload.
|
||||
|
@ -473,7 +422,7 @@ let TelemetryScheduler = {
|
|||
timeout = SCHEDULER_TICK_IDLE_INTERVAL_MS;
|
||||
// We need to make sure though that we don't miss sending pings around
|
||||
// midnight when we use the longer idle intervals.
|
||||
const nextMidnight = getNextMidnight(now);
|
||||
const nextMidnight = TelemetryUtils.getNextMidnight(now);
|
||||
timeout = Math.min(timeout, nextMidnight.getTime() - now.getTime());
|
||||
}
|
||||
|
||||
|
@ -484,8 +433,8 @@ let TelemetryScheduler = {
|
|||
|
||||
_sentDailyPingToday: function(nowDate) {
|
||||
// This is today's date and also the previous midnight (0:00).
|
||||
const todayDate = truncateToDays(nowDate);
|
||||
const nearestMidnight = getNearestMidnight(nowDate);
|
||||
const todayDate = TelemetryUtils.truncateToDays(nowDate);
|
||||
const nearestMidnight = TelemetryUtils.getNearestMidnight(nowDate, SCHEDULER_MIDNIGHT_TOLERANCE_MS);
|
||||
// If we are close to midnight, we check against that, otherwise against the last midnight.
|
||||
const checkDate = nearestMidnight || todayDate;
|
||||
// We consider a ping sent for today if it occured after midnight, or prior within the tolerance.
|
||||
|
@ -506,7 +455,7 @@ let TelemetryScheduler = {
|
|||
return false;
|
||||
}
|
||||
|
||||
const nearestMidnight = getNearestMidnight(nowDate);
|
||||
const nearestMidnight = TelemetryUtils.getNearestMidnight(nowDate, SCHEDULER_MIDNIGHT_TOLERANCE_MS);
|
||||
if (!sentPingToday && !nearestMidnight) {
|
||||
// Computer must have gone to sleep, the daily ping is overdue.
|
||||
this._log.trace("_isDailyPingDue - daily ping is overdue... computer went to sleep?");
|
||||
|
@ -616,7 +565,8 @@ let TelemetryScheduler = {
|
|||
let nextSessionCheckpoint =
|
||||
this._lastSessionCheckpointTime + ABORTED_SESSION_UPDATE_INTERVAL_MS;
|
||||
let combineActions = (shouldSendDaily && isAbortedPingDue) || (shouldSendDaily &&
|
||||
areTimesClose(now, nextSessionCheckpoint, SCHEDULER_COALESCE_THRESHOLD_MS));
|
||||
TelemetryUtils.areTimesClose(now, nextSessionCheckpoint,
|
||||
SCHEDULER_COALESCE_THRESHOLD_MS));
|
||||
|
||||
if (combineActions) {
|
||||
this._log.trace("_schedulerTickLogic - Combining pings.");
|
||||
|
@ -661,7 +611,7 @@ let TelemetryScheduler = {
|
|||
// update the schedules.
|
||||
this._saveAbortedPing(now.getTime(), competingPayload);
|
||||
// If we're close to midnight, skip today's daily ping and reschedule it for tomorrow.
|
||||
let nearestMidnight = getNearestMidnight(now);
|
||||
let nearestMidnight = TelemetryUtils.getNearestMidnight(now, SCHEDULER_MIDNIGHT_TOLERANCE_MS);
|
||||
if (nearestMidnight) {
|
||||
this._lastDailyPingTime = now.getTime();
|
||||
}
|
||||
|
@ -1152,8 +1102,8 @@ let Impl = {
|
|||
getMetadata: function getMetadata(reason) {
|
||||
this._log.trace("getMetadata - Reason " + reason);
|
||||
|
||||
let sessionStartDate = toLocalTimeISOString(truncateToDays(this._sessionStartDate));
|
||||
let subsessionStartDate = toLocalTimeISOString(truncateToDays(this._subsessionStartDate));
|
||||
let sessionStartDate = toLocalTimeISOString(TelemetryUtils.truncateToDays(this._sessionStartDate));
|
||||
let subsessionStartDate = toLocalTimeISOString(TelemetryUtils.truncateToDays(this._subsessionStartDate));
|
||||
// Compute the subsession length in milliseconds, then convert to seconds.
|
||||
let subsessionLength =
|
||||
Math.floor((Policy.now() - this._subsessionStartDate.getTime()) / 1000);
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
this.EXPORTED_SYMBOLS = [
|
||||
"TelemetryUtils"
|
||||
];
|
||||
|
||||
const {classes: Cc, interfaces: Ci, results: Cr, utils: Cu} = Components;
|
||||
|
||||
this.TelemetryUtils = {
|
||||
/**
|
||||
* Takes a date and returns it trunctated to a date with daily precision.
|
||||
*/
|
||||
truncateToDays: function(date) {
|
||||
return new Date(date.getFullYear(),
|
||||
date.getMonth(),
|
||||
date.getDate(),
|
||||
0, 0, 0, 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if the difference between the times is within the provided tolerance.
|
||||
* @param {Number} t1 A time in milliseconds.
|
||||
* @param {Number} t2 A time in milliseconds.
|
||||
* @param {Number} tolerance The tolerance, in milliseconds.
|
||||
* @return {Boolean} True if the absolute time difference is within the tolerance, false
|
||||
* otherwise.
|
||||
*/
|
||||
areTimesClose: function(t1, t2, tolerance) {
|
||||
return Math.abs(t1 - t2) <= tolerance;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the next midnight for a date.
|
||||
* @param {Object} date The date object to check.
|
||||
* @return {Object} The Date object representing the next midnight.
|
||||
*/
|
||||
getNextMidnight: function(date) {
|
||||
let nextMidnight = new Date(this.truncateToDays(date));
|
||||
nextMidnight.setDate(nextMidnight.getDate() + 1);
|
||||
return nextMidnight;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the midnight which is closer to the provided date.
|
||||
* @param {Object} date The date object to check.
|
||||
* @param {Number} tolerance The tolerance within we find the closest midnight.
|
||||
* @return {Object} The Date object representing the closes midnight, or null if midnight
|
||||
* is not within the midnight tolerance.
|
||||
*/
|
||||
getNearestMidnight: function(date, tolerance) {
|
||||
let lastMidnight = this.truncateToDays(date);
|
||||
if (this.areTimesClose(date.getTime(), lastMidnight.getTime(), tolerance)) {
|
||||
return lastMidnight;
|
||||
}
|
||||
|
||||
const nextMidnightDate = this.getNextMidnight(date);
|
||||
if (this.areTimesClose(date.getTime(), nextMidnightDate.getTime(), tolerance)) {
|
||||
return nextMidnightDate;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
};
|
|
@ -34,6 +34,7 @@ EXTRA_JS_MODULES += [
|
|||
'TelemetryLog.jsm',
|
||||
'TelemetryStopwatch.jsm',
|
||||
'TelemetryStorage.jsm',
|
||||
'TelemetryUtils.jsm',
|
||||
'ThirdPartyCookieProbe.jsm',
|
||||
'UITelemetry.jsm',
|
||||
]
|
||||
|
|
|
@ -287,14 +287,14 @@ add_task(function* test_midnightPingSendFuzzing() {
|
|||
yield sendPing(true, true);
|
||||
|
||||
Assert.ok(!!pingSendTimerCallback);
|
||||
Assert.deepEqual(futureDate(now, pingSendTimeout), new Date(2030, 5, 2, 0, 45, 0));
|
||||
Assert.deepEqual(futureDate(now, pingSendTimeout), new Date(2030, 5, 2, 1, 0, 0));
|
||||
|
||||
// A ping after midnight within the fuzzing delay should also not get sent.
|
||||
now = new Date(2030, 5, 2, 0, 40, 0);
|
||||
fakeNow(now);
|
||||
pingSendTimeout = null;
|
||||
yield sendPing(true, true);
|
||||
Assert.deepEqual(futureDate(now, pingSendTimeout), new Date(2030, 5, 2, 0, 45, 0));
|
||||
Assert.deepEqual(futureDate(now, pingSendTimeout), new Date(2030, 5, 2, 1, 0, 0));
|
||||
|
||||
// The Request constructor restores the previous ping handler.
|
||||
gRequestIterator = Iterator(new Request());
|
||||
|
|
|
@ -1672,7 +1672,7 @@ add_task(function* test_sendDailyOnIdle() {
|
|||
Assert.equal(ping.payload.info.reason, REASON_DAILY);
|
||||
|
||||
// We should also trigger a ping when going idle shortly before next midnight.
|
||||
now = new Date(2040, 1, 2, 23, 55, 0);
|
||||
now = new Date(2040, 1, 2, 23, 54, 0);
|
||||
fakeNow(now);
|
||||
yield fakeIdleNotification("idle");
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче