in glean/src/core/metrics/events_database/index.ts [328:417]
private prepareEventsPayload(pingName: string, pingData: RecordedEvent[]): JSONArray {
// Sort events by execution counter and by timestamp.
let sortedEvents = pingData.sort((a, b) => {
const executionCounterA = Number(a.get().extra?.[GLEAN_EXECUTION_COUNTER_EXTRA_KEY]);
const executionCounterB = Number(b.get().extra?.[GLEAN_EXECUTION_COUNTER_EXTRA_KEY]);
// Sort by execution counter, in case they are different.
if (executionCounterA !== executionCounterB) {
return executionCounterA - executionCounterB;
}
// Sort by timestamp if events come from same execution.
return a.get().timestamp - b.get().timestamp;
});
let lastRestartDate: Date;
try {
lastRestartDate = createDateObject(
sortedEvents[0].get().extra?.[GLEAN_REFERENCE_TIME_EXTRA_KEY]
);
// Drop the first `restarted` event.
sortedEvents.shift();
} catch {
// In the unlikely case that the first event was not a `glean.restarted` event,
// let's rely on the start time of the current session.
lastRestartDate = Context.startTime;
}
const firstEventOffset = sortedEvents[0]?.get().timestamp || 0;
let restartedOffset = 0;
for (const [index, event] of sortedEvents.entries()) {
try {
const nextRestartDate = createDateObject(
event.get().extra?.[GLEAN_REFERENCE_TIME_EXTRA_KEY]
);
const dateOffset = nextRestartDate.getTime() - lastRestartDate.getTime();
lastRestartDate = nextRestartDate;
// Calculate the new offset since new restart.
const newRestartedOffset = restartedOffset + dateOffset;
// The restarted event is always timestamp 0,
// so in order to guarantee event timestamps are always in ascending order,
// the offset needs to be _at least_ larger than the previous timestamp.
const previousEventTimestamp = sortedEvents[index - 1].get().timestamp;
if (newRestartedOffset <= previousEventTimestamp) {
// In case the new offset results in descending timestamps,
// we increase the previous timestamp by one to make sure
// timestamps keep increasing.
restartedOffset = previousEventTimestamp + 1;
Context.errorManager.record(
getGleanRestartedEventMetric([pingName]),
ErrorType.InvalidValue,
`Invalid time offset between application sessions found for ping "${pingName}". Ignoring.`
);
} else {
restartedOffset = newRestartedOffset;
}
} catch {
// Do nothing,
// this is expected to fail in case the current event is not a `glean.restarted` event.
}
// Apply necessary offsets to timestamps:
// 1. If it is the first execution, subtract the firstEventOffset;
// 2. Otherwise add restartedOffset.
// The execution counter is a counter metric, the smallest value it can have is `1`.
// At this stage all metrics should have an execution counter, but out of caution we
// will fallback to `1` in case it is not present.
const executionCount = Number(event.get().extra?.[GLEAN_EXECUTION_COUNTER_EXTRA_KEY] || 1);
let adjustedTimestamp: number;
if (executionCount === 1) {
adjustedTimestamp = event.get().timestamp - firstEventOffset;
} else {
adjustedTimestamp = event.get().timestamp + restartedOffset;
}
sortedEvents[index] = new RecordedEvent({
category: event.get().category,
name: event.get().name,
timestamp: adjustedTimestamp,
extra: event.get().extra
});
}
// There is no additional context in trailing `glean.restarted` events, they can be removed.
sortedEvents = removeTrailingRestartedEvents(sortedEvents);
return sortedEvents.map((e) => e.payload());
}