fn process_dir()

in glean-core/src/upload/directory.rs [270:331]


    fn process_dir(&self, dir: &Path) -> Vec<(u64, PingPayload)> {
        log::trace!("Processing persisted pings.");

        let entries = match dir.read_dir() {
            Ok(entries) => entries,
            Err(_) => {
                // This may error simply because the directory doesn't exist,
                // which is expected if no pings were stored yet.
                return Vec::new();
            }
        };

        let mut pending_pings: Vec<_> = entries
            .filter_map(|entry| entry.ok())
            .filter_map(|entry| {
                let path = entry.path();
                if let Some(file_name) = get_file_name_as_str(&path) {
                    // Delete file if it doesn't match the pattern.
                    if Uuid::parse_str(file_name).is_err() {
                        log::warn!("Pattern mismatch. Deleting {}", path.display());
                        self.delete_file(file_name);
                        return None;
                    }
                    if let Some(data) = self.process_file(file_name) {
                        let metadata = match fs::metadata(&path) {
                            Ok(metadata) => metadata,
                            Err(e) => {
                                // There's a rare case where this races against a parallel deletion
                                // of all pending ping files.
                                // This could therefore fail, in which case we don't care about the
                                // result and can ignore the ping, it's already been deleted.
                                log::warn!(
                                    "Unable to read metadata for file: {}, error: {:?}",
                                    path.display(),
                                    e
                                );
                                return None;
                            }
                        };
                        return Some((metadata, data));
                    }
                };
                None
            })
            .collect();

        // This will sort the pings by date in ascending order (oldest -> newest).
        pending_pings.sort_by(|(a, _), (b, _)| {
            // We might not be able to get the modified date for a given file,
            // in which case we just put it at the end.
            if let (Ok(a), Ok(b)) = (a.modified(), b.modified()) {
                a.cmp(&b)
            } else {
                Ordering::Less
            }
        });

        pending_pings
            .into_iter()
            .map(|(metadata, data)| (metadata.len(), data))
            .collect()
    }