in glean-core/src/upload/mod.rs [476:553]
fn enqueue_cached_pings(&self, glean: &Glean) {
let mut cached_pings = self
.cached_pings
.write()
.expect("Can't write to pending pings cache.");
if cached_pings.len() > 0 {
let mut pending_pings_directory_size: u64 = 0;
let mut pending_pings_count = 0;
let mut deleting = false;
let total = cached_pings.pending_pings.len() as u64;
self.upload_metrics
.pending_pings
.add_sync(glean, total.try_into().unwrap_or(0));
if total > self.policy.max_pending_pings_count() {
log::warn!(
"More than {} pending pings in the directory, will delete {} old pings.",
self.policy.max_pending_pings_count(),
total - self.policy.max_pending_pings_count()
);
}
// The pending pings vector is sorted by date in ascending order (oldest -> newest).
// We need to calculate the size of the pending pings directory
// and delete the **oldest** pings in case quota is reached.
// Thus, we reverse the order of the pending pings vector,
// so that we iterate in descending order (newest -> oldest).
cached_pings.pending_pings.reverse();
cached_pings.pending_pings.retain(|(file_size, PingPayload {document_id, ..})| {
pending_pings_count += 1;
pending_pings_directory_size += file_size;
// We don't want to spam the log for every ping over the quota.
if !deleting && pending_pings_directory_size > self.policy.max_pending_pings_directory_size() {
log::warn!(
"Pending pings directory has reached the size quota of {} bytes, outstanding pings will be deleted.",
self.policy.max_pending_pings_directory_size()
);
deleting = true;
}
// Once we reach the number of allowed pings we start deleting,
// no matter what size.
// We already log this before the loop.
if pending_pings_count > self.policy.max_pending_pings_count() {
deleting = true;
}
if deleting && self.directory_manager.delete_file(document_id) {
self.upload_metrics
.deleted_pings_after_quota_hit
.add_sync(glean, 1);
return false;
}
true
});
// After calculating the size of the pending pings directory,
// we record the calculated number and reverse the pings array back for enqueueing.
cached_pings.pending_pings.reverse();
self.upload_metrics
.pending_pings_directory_size
.accumulate_sync(glean, pending_pings_directory_size as i64 / 1024);
// Enqueue the remaining pending pings and
// enqueue all deletion-request pings.
cached_pings
.deletion_request_pings
.drain(..)
.for_each(|(_, ping)| self.enqueue_ping(glean, ping));
cached_pings
.pending_pings
.drain(..)
.for_each(|(_, ping)| self.enqueue_ping(glean, ping));
}
}