Skip to main content

nexrad_data/aws/realtime/
get_latest_volume.rs

1use crate::aws::realtime::list_chunks_in_volume::list_chunks_in_volume;
2use crate::aws::realtime::search::search;
3use crate::aws::realtime::VolumeIndex;
4use chrono::{DateTime, Utc};
5use std::sync::atomic::AtomicI32;
6use std::sync::atomic::Ordering::Relaxed;
7use std::sync::Arc;
8
9/// Identifies the volume index with the most recent data for the specified radar site. Real-time
10/// NEXRAD data is uploaded to a series of rotating volumes 0..=999, each containing ~55 chunks.
11/// This function performs a binary search to find the most recent volume with data.
12pub async fn get_latest_volume(site: &str) -> crate::result::Result<LatestVolumeResult> {
13    let calls = Arc::new(AtomicI32::new(0));
14    let latest_volume = search(998, DateTime::<Utc>::MAX_UTC, |volume| {
15        calls.fetch_add(1, Relaxed);
16        async move {
17            let chunks = list_chunks_in_volume(site, VolumeIndex::new(volume + 1), 1).await?;
18            Ok(chunks.first().and_then(|chunk| chunk.date_time()))
19        }
20    })
21    .await
22    .map(|volume| volume.map(|index| VolumeIndex::new(index + 1)))?;
23
24    Ok(LatestVolumeResult {
25        volume: latest_volume,
26        calls: calls.load(Relaxed) as usize,
27    })
28}
29
30/// Represents the most recent volume index and the number of network calls made to find it.
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub struct LatestVolumeResult {
33    /// The most recent volume index, if found.
34    pub volume: Option<VolumeIndex>,
35
36    /// The number of network calls made to find the most recent volume.
37    pub calls: usize,
38}