use dbsp::storage::backend::posixio_impl::PosixBackend;
use feldera_storage::metrics::{COMMIT_ALL_LATENCY_MICROSECONDS, SYNC_LATENCY_MICROSECONDS};
use feldera_storage::{FileCommitter, StorageBackend, fbuf::FBuf};
use feldera_types::config::{FileBackendConfig, StorageCacheConfig, StorageSyncMode};
use std::sync::Arc;
const FILES: usize = 12;
fn backend(path: &std::path::Path, sync_mode: StorageSyncMode) -> Arc<dyn StorageBackend> {
Arc::new(PosixBackend::new(
path,
StorageCacheConfig::default(),
&FileBackendConfig {
sync_mode: Some(sync_mode),
..Default::default()
},
))
}
fn write_files(backend: &Arc<dyn StorageBackend>) -> Vec<Arc<dyn FileCommitter>> {
(0..FILES)
.map(|i| {
let path = format!("file-{i}").into();
backend
.write(&path, FBuf::from_slice(&[i as u8; 512]))
.unwrap()
})
.collect()
}
fn counts() -> (u64, u64) {
let total = |histogram: &feldera_storage::histogram::ExponentialHistogram| {
histogram
.snapshot()
.iter_buckets()
.map(|bucket| bucket.count)
.sum()
};
(
total(&SYNC_LATENCY_MICROSECONDS),
total(&COMMIT_ALL_LATENCY_MICROSECONDS),
)
}
#[test]
fn commit_all_batches_by_strategy() {
let tmpdir = tempfile::tempdir().unwrap();
assert_eq!(counts(), (0, 0), "test must own the process");
let per_file = backend(&tmpdir.path().join("per-file"), StorageSyncMode::PerFile);
let files = write_files(&per_file);
assert_eq!(counts(), (0, 0), "writing must not sync");
per_file.commit_all(&files).unwrap();
assert_eq!(
counts(),
(FILES as u64, 1),
"per_file fsyncs each file, and the call is timed once"
);
#[cfg(not(target_os = "linux"))]
let _ = tmpdir;
#[cfg(target_os = "linux")]
syncfs_half(&tmpdir);
}
#[cfg(target_os = "linux")]
fn syncfs_half(tmpdir: &tempfile::TempDir) {
let syncfs = backend(&tmpdir.path().join("syncfs"), StorageSyncMode::Syncfs);
let files = write_files(&syncfs);
assert_eq!(counts(), (FILES as u64, 1), "writing must not sync");
syncfs.commit_all(&files).unwrap();
assert_eq!(
counts(),
(FILES as u64, 2),
"syncfs fsyncs no individual file, and the call is timed once"
);
syncfs.commit_all(&[]).unwrap();
assert_eq!(
counts(),
(FILES as u64, 2),
"no files means no sync and no timing"
);
}