Skip to content

Commit 7fcf0b8

Browse files
ygndotggparmesant
authored andcommitted
track insertion time instead of data time for eviction
1 parent 169c998 commit 7fcf0b8

2 files changed

Lines changed: 41 additions & 14 deletions

File tree

src/storage/object_storage.rs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use crate::storage::TARGETS_ROOT_DIRECTORY;
6363
use crate::storage::field_stats::DATASET_STATS_STREAM_NAME;
6464
use crate::storage::field_stats::calculate_field_stats;
6565
use crate::storage::field_stats::extract_datetime_from_parquet_path_regex;
66-
use crate::sync::ACTIVE_OBJECT_STORE_SYNC_FILES;
66+
use crate::sync::{ACTIVE_OBJECT_STORE_SYNC_FILES, SyncFileEntry};
6767
use crate::sync::FLUSH_AND_CONVERT_RUNTIME;
6868

6969
use super::{
@@ -1090,14 +1090,21 @@ async fn process_parquet_files(
10901090
let parquet_paths: Vec<PathBuf> = upload_context
10911091
.stream
10921092
.parquet_files()
1093-
.into_iter()
1094-
.filter(|p| !guard.contains(p))
1093+
.into_par_iter()
1094+
.filter(|p| !guard.contains_key(p))
10951095
.collect();
10961096

10971097
let mut ret = Vec::with_capacity(parquet_paths.len());
10981098
ret.clone_from(&parquet_paths);
1099-
guard.extend(parquet_paths);
1100-
tracing::info!(ACTIVE_OBJECT_STORE_SYNC_FILES=?ACTIVE_OBJECT_STORE_SYNC_FILES);
1099+
for path in parquet_paths {
1100+
guard.insert(
1101+
path,
1102+
SyncFileEntry {
1103+
tracked_instant: Instant::now(),
1104+
tracked_utc: Utc::now(),
1105+
},
1106+
);
1107+
}
11011108
ret
11021109
};
11031110

@@ -1283,11 +1290,23 @@ async fn cleanup_uploaded_staged_files(uploaded_files: Vec<UploadedParquetFile>)
12831290
guard.remove(path);
12841291
}
12851292

1286-
// check if file has been in hashset for more than 5 minutes
1287-
let now = Utc::now();
1288-
guard.retain(|f| {
1289-
!extract_datetime_from_parquet_path_regex(f)
1290-
.is_ok_and(|ts| (now - ts).num_minutes() >= 5)
1293+
// Use monotonic time to ensure the 5-minute eviction window is immune to system clock adjustments.
1294+
let now = Instant::now();
1295+
guard.retain(|path, entry| {
1296+
let elapsed = now.duration_since(entry.tracked_instant);
1297+
// 5 min eviction window
1298+
if elapsed >= Duration::from_secs(300) {
1299+
// Added log for observability and debugging
1300+
warn!(
1301+
"Removing stale sync file: {} (elapsed: {}s, tracked_at: {})",
1302+
path.display(),
1303+
elapsed.as_secs(),
1304+
entry.tracked_utc.to_rfc3339(),
1305+
);
1306+
false
1307+
} else {
1308+
true
1309+
}
12911310
});
12921311
}
12931312

src/sync.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
*
1717
*/
1818

19-
use chrono::{TimeDelta, Timelike};
20-
use datafusion::common::HashSet;
19+
use chrono::{DateTime, TimeDelta, Timelike, Utc};
2120
use futures::FutureExt;
2221
use once_cell::sync::Lazy;
2322
use std::collections::HashMap;
@@ -39,8 +38,17 @@ pub static FLUSH_AND_CONVERT_RUNTIME: Lazy<Runtime> =
3938
static LOCAL_SYNC_RUNNING: AtomicBool = AtomicBool::new(false);
4039
static REMOTE_SYNC_RUNNING: AtomicBool = AtomicBool::new(false);
4140

42-
pub static ACTIVE_OBJECT_STORE_SYNC_FILES: Lazy<Arc<RwLock<HashSet<PathBuf>>>> =
43-
Lazy::new(|| Arc::new(RwLock::new(HashSet::new())));
41+
// tracks metadata for files being synced to object storage
42+
#[derive(Clone, Debug)]
43+
pub struct SyncFileEntry {
44+
// Monotonic instant when file was added to tracking
45+
pub tracked_instant: std::time::Instant,
46+
// Wall-clock UTC timestamp for observability
47+
pub tracked_utc: DateTime<Utc>,
48+
}
49+
50+
pub static ACTIVE_OBJECT_STORE_SYNC_FILES: Lazy<Arc<RwLock<HashMap<PathBuf, SyncFileEntry>>>> =
51+
Lazy::new(|| Arc::new(RwLock::new(HashMap::new())));
4452
/// RAII guard that clears a sync-running flag on drop, so a panic inside the
4553
/// sync body cannot leave the flag stuck at `true` and wedge future ticks.
4654
struct SyncRunningGuard(&'static AtomicBool);

0 commit comments

Comments
 (0)