Run one tiering cycle against the given segments directory. Uploads eligible segment files (older than `tier_after`) to the cold store under `{prefix}segments/{filename}`, then removes the local copies.
(
cold: &crate::storage::cold::ColdStorage,
segments_dir: &std::path::Path,
tier_after: Duration,
prefix: &str,
)
| 74 | /// Uploads eligible segment files (older than `tier_after`) to the cold store |
| 75 | /// under `{prefix}segments/{filename}`, then removes the local copies. |
| 76 | pub(crate) async fn run_tier_cycle_at( |
| 77 | cold: &crate::storage::cold::ColdStorage, |
| 78 | segments_dir: &std::path::Path, |
| 79 | tier_after: Duration, |
| 80 | prefix: &str, |
| 81 | ) { |
| 82 | let now = SystemTime::now(); |
| 83 | |
| 84 | let entries = match read_dir_sync(segments_dir).await { |
| 85 | Ok(e) => e, |
| 86 | Err(e) => { |
| 87 | warn!( |
| 88 | error = %e, |
| 89 | dir = %segments_dir.display(), |
| 90 | "cold tier: failed to read segments directory" |
| 91 | ); |
| 92 | return; |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | let mut tiered: u64 = 0; |
| 97 | let mut errors: u64 = 0; |
| 98 | |
| 99 | for entry_path in entries { |
| 100 | let age = match file_age(&entry_path, now) { |
| 101 | Some(a) => a, |
| 102 | None => { |
| 103 | debug!(path = %entry_path.display(), "cold tier: skipping entry (mtime unavailable)"); |
| 104 | continue; |
| 105 | } |
| 106 | }; |
| 107 | |
| 108 | if age < tier_after { |
| 109 | debug!( |
| 110 | path = %entry_path.display(), |
| 111 | age_secs = age.as_secs(), |
| 112 | "cold tier: segment too recent, skipping" |
| 113 | ); |
| 114 | continue; |
| 115 | } |
| 116 | |
| 117 | let segment_name = match entry_path.file_name().and_then(|n| n.to_str()) { |
| 118 | Some(n) => n.to_owned(), |
| 119 | None => { |
| 120 | warn!(path = %entry_path.display(), "cold tier: invalid segment filename, skipping"); |
| 121 | continue; |
| 122 | } |
| 123 | }; |
| 124 | |
| 125 | let object_path = format!("{}segments/{}", prefix, segment_name); |
| 126 | let entry_path_clone = entry_path.clone(); |
| 127 | |
| 128 | match upload_raw_segment(cold, &entry_path_clone, &object_path).await { |
| 129 | Ok(()) => { |
| 130 | info!( |
| 131 | segment = %segment_name, |
| 132 | object_path = %object_path, |
| 133 | age_secs = age.as_secs(), |
no test coverage detected