Skip to content

Commit e483fa4

Browse files
committed
refactor more
1 parent e0565df commit e483fa4

18 files changed

Lines changed: 376 additions & 73 deletions

File tree

kernel/src/actions/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1712,7 +1712,7 @@ mod tests {
17121712
fn test_commit_info_into_engine_data() {
17131713
let engine = ExprEngine::new();
17141714

1715-
let commit_info = CommitInfo::new(0, None, None, None);
1715+
let commit_info = CommitInfo::new(0, None, None);
17161716
let commit_info_txn_id = commit_info.txn_id.clone();
17171717

17181718
let engine_data = commit_info.into_engine_data(CommitInfo::to_schema().into(), &engine);

kernel/src/checkpoint/tests.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,11 @@ fn test_deleted_file_retention_timestamp() -> DeltaResult<()> {
6060
#[test]
6161
fn test_create_checkpoint_metadata_batch() -> DeltaResult<()> {
6262
let (store, _) = new_in_memory_store();
63-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
63+
let engine = DefaultEngine::new(
64+
store.clone(),
65+
Arc::new(TokioBackgroundExecutor::new()),
66+
None,
67+
);
6468

6569
// 1st commit (version 0) - metadata and protocol actions
6670
// Protocol action does not include the v2Checkpoint reader/writer feature.
@@ -116,7 +120,11 @@ fn test_create_last_checkpoint_data() -> DeltaResult<()> {
116120
let add_actions_counter = 75;
117121
let size_in_bytes: i64 = 1024 * 1024; // 1MB
118122
let (store, _) = new_in_memory_store();
119-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
123+
let engine = DefaultEngine::new(
124+
store.clone(),
125+
Arc::new(TokioBackgroundExecutor::new()),
126+
None,
127+
);
120128

121129
// Create last checkpoint metadata
122130
let last_checkpoint_batch = create_last_checkpoint_data(
@@ -277,7 +285,11 @@ fn read_last_checkpoint_file(store: &Arc<InMemory>) -> DeltaResult<Value> {
277285
#[test]
278286
fn test_v1_checkpoint_latest_version_by_default() -> DeltaResult<()> {
279287
let (store, _) = new_in_memory_store();
280-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
288+
let engine = DefaultEngine::new(
289+
store.clone(),
290+
Arc::new(TokioBackgroundExecutor::new()),
291+
None,
292+
);
281293

282294
// 1st commit: adds `fake_path_1`
283295
write_commit_to_store(&store, vec![create_add_action("fake_path_1")], 0)?;
@@ -347,7 +359,11 @@ fn test_v1_checkpoint_latest_version_by_default() -> DeltaResult<()> {
347359
#[test]
348360
fn test_v1_checkpoint_specific_version() -> DeltaResult<()> {
349361
let (store, _) = new_in_memory_store();
350-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
362+
let engine = DefaultEngine::new(
363+
store.clone(),
364+
Arc::new(TokioBackgroundExecutor::new()),
365+
None,
366+
);
351367

352368
// 1st commit (version 0) - metadata and protocol actions
353369
// Protocol action does not include the v2Checkpoint reader/writer feature.
@@ -409,7 +425,11 @@ fn test_v1_checkpoint_specific_version() -> DeltaResult<()> {
409425
#[test]
410426
fn test_finalize_errors_if_checkpoint_data_iterator_is_not_exhausted() -> DeltaResult<()> {
411427
let (store, _) = new_in_memory_store();
412-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
428+
let engine = DefaultEngine::new(
429+
store.clone(),
430+
Arc::new(TokioBackgroundExecutor::new()),
431+
None,
432+
);
413433

414434
// 1st commit (version 0) - metadata and protocol actions
415435
write_commit_to_store(
@@ -451,7 +471,11 @@ fn test_finalize_errors_if_checkpoint_data_iterator_is_not_exhausted() -> DeltaR
451471
#[test]
452472
fn test_v2_checkpoint_supported_table() -> DeltaResult<()> {
453473
let (store, _) = new_in_memory_store();
454-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
474+
let engine = DefaultEngine::new(
475+
store.clone(),
476+
Arc::new(TokioBackgroundExecutor::new()),
477+
None,
478+
);
455479

456480
// 1st commit: adds `fake_path_2` & removes `fake_path_1`
457481
write_commit_to_store(
@@ -523,7 +547,11 @@ fn test_v2_checkpoint_supported_table() -> DeltaResult<()> {
523547
#[test]
524548
fn test_no_checkpoint_staged_commits() -> DeltaResult<()> {
525549
let (store, _) = new_in_memory_store();
526-
let engine = DefaultEngine::new(store.clone(), Arc::new(TokioBackgroundExecutor::new()));
550+
let engine = DefaultEngine::new(
551+
store.clone(),
552+
Arc::new(TokioBackgroundExecutor::new()),
553+
None,
554+
);
527555

528556
// normal commit
529557
write_commit_to_store(

kernel/src/committer.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,11 @@ mod tests {
212212
async fn catalog_managed_tables_block_transactions() {
213213
let storage = Arc::new(InMemory::new());
214214
let table_root = Url::parse("memory:///").unwrap();
215-
let engine = DefaultEngine::new(storage.clone(), Arc::new(TokioBackgroundExecutor::new()));
215+
let engine = DefaultEngine::new(
216+
storage.clone(),
217+
Arc::new(TokioBackgroundExecutor::new()),
218+
None,
219+
);
216220

217221
let actions = [
218222
r#"{"commitInfo":{"timestamp":12345678900,"inCommitTimestamp":12345678900}}"#,

kernel/src/engine/default/filesystem.rs

Lines changed: 128 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,102 @@ use url::Url;
1010

1111
use super::UrlExt;
1212
use crate::engine::default::executor::TaskExecutor;
13+
use crate::metrics::{MetricEvent, MetricsReporter, Timer};
1314
use crate::{DeltaResult, Error, FileMeta, FileSlice, StorageHandler};
1415

16+
/// Iterator wrapper that emits metrics when exhausted
17+
struct ListMetricsIterator<I> {
18+
inner: I,
19+
reporter: Option<Arc<dyn MetricsReporter>>,
20+
timer: Timer,
21+
count: u64,
22+
metrics_emitted: bool,
23+
}
24+
25+
impl<I: Iterator<Item = DeltaResult<FileMeta>>> Iterator for ListMetricsIterator<I> {
26+
type Item = DeltaResult<FileMeta>;
27+
28+
fn next(&mut self) -> Option<Self::Item> {
29+
match self.inner.next() {
30+
Some(item) => {
31+
if item.is_ok() {
32+
self.count += 1;
33+
}
34+
Some(item)
35+
}
36+
None => {
37+
if !self.metrics_emitted {
38+
if let Some(ref r) = self.reporter {
39+
r.report(MetricEvent::StorageListCompleted {
40+
duration: self.timer.elapsed(),
41+
num_files: self.count,
42+
});
43+
}
44+
self.metrics_emitted = true;
45+
}
46+
None
47+
}
48+
}
49+
}
50+
}
51+
52+
/// Iterator wrapper for read operations that tracks bytes read
53+
struct ReadMetricsIterator<I> {
54+
inner: I,
55+
reporter: Option<Arc<dyn MetricsReporter>>,
56+
timer: Timer,
57+
num_files: u64,
58+
bytes_read: u64,
59+
metrics_emitted: bool,
60+
}
61+
62+
impl<I: Iterator<Item = DeltaResult<Bytes>>> Iterator for ReadMetricsIterator<I> {
63+
type Item = DeltaResult<Bytes>;
64+
65+
fn next(&mut self) -> Option<Self::Item> {
66+
match self.inner.next() {
67+
Some(item) => {
68+
if let Ok(ref bytes) = item {
69+
self.bytes_read += bytes.len() as u64;
70+
}
71+
Some(item)
72+
}
73+
None => {
74+
if !self.metrics_emitted {
75+
if let Some(ref r) = self.reporter {
76+
r.report(MetricEvent::StorageReadCompleted {
77+
duration: self.timer.elapsed(),
78+
num_files: self.num_files,
79+
bytes_read: self.bytes_read,
80+
});
81+
}
82+
self.metrics_emitted = true;
83+
}
84+
None
85+
}
86+
}
87+
}
88+
}
89+
1590
#[derive(Debug)]
1691
pub struct ObjectStoreStorageHandler<E: TaskExecutor> {
1792
inner: Arc<DynObjectStore>,
1893
task_executor: Arc<E>,
94+
reporter: Option<Arc<dyn MetricsReporter>>,
1995
readahead: usize,
2096
}
2197

2298
impl<E: TaskExecutor> ObjectStoreStorageHandler<E> {
2399
#[internal_api]
24-
pub(crate) fn new(store: Arc<DynObjectStore>, task_executor: Arc<E>) -> Self {
100+
pub(crate) fn new(
101+
store: Arc<DynObjectStore>,
102+
task_executor: Arc<E>,
103+
reporter: Option<Arc<dyn MetricsReporter>>,
104+
) -> Self {
25105
Self {
26106
inner: store,
27107
task_executor,
108+
reporter,
28109
readahead: 10,
29110
}
30111
}
@@ -106,13 +187,31 @@ impl<E: TaskExecutor> StorageHandler for ObjectStoreStorageHandler<E> {
106187
}
107188
});
108189

190+
let timer = Timer::new();
191+
let reporter = self.reporter.clone();
192+
109193
if !has_ordered_listing {
110194
// This FS doesn't return things in the order we require
111195
let mut fms: Vec<FileMeta> = receiver.into_iter().try_collect()?;
112196
fms.sort_unstable();
197+
198+
let num_files = fms.len() as u64;
199+
if let Some(ref r) = reporter {
200+
r.report(MetricEvent::StorageListCompleted {
201+
duration: timer.elapsed(),
202+
num_files,
203+
});
204+
}
205+
113206
Ok(Box::new(fms.into_iter().map(Ok)))
114207
} else {
115-
Ok(Box::new(receiver.into_iter()))
208+
Ok(Box::new(ListMetricsIterator {
209+
inner: receiver.into_iter(),
210+
reporter,
211+
timer,
212+
count: 0,
213+
metrics_emitted: false,
214+
}))
116215
}
117216
}
118217

@@ -127,6 +226,7 @@ impl<E: TaskExecutor> StorageHandler for ObjectStoreStorageHandler<E> {
127226
files: Vec<FileSlice>,
128227
) -> DeltaResult<Box<dyn Iterator<Item = DeltaResult<Bytes>>>> {
129228
let store = self.inner.clone();
229+
let num_files = files.len() as u64;
130230

131231
// This channel will become the output iterator.
132232
// Because there will already be buffering in the stream, we set the
@@ -173,19 +273,28 @@ impl<E: TaskExecutor> StorageHandler for ObjectStoreStorageHandler<E> {
173273
}),
174274
);
175275

176-
Ok(Box::new(receiver.into_iter()))
276+
Ok(Box::new(ReadMetricsIterator {
277+
inner: receiver.into_iter(),
278+
reporter: self.reporter.clone(),
279+
timer: Timer::new(),
280+
num_files,
281+
bytes_read: 0,
282+
metrics_emitted: false,
283+
}))
177284
}
178285

179286
fn copy_atomic(&self, src: &Url, dest: &Url) -> DeltaResult<()> {
287+
let timer = Timer::new();
180288
let src_path = Path::from_url_path(src.path())?;
181289
let dest_path = Path::from_url_path(dest.path())?;
182290
let dest_path_str = dest_path.to_string();
183291
let store = self.inner.clone();
292+
let reporter = self.reporter.clone();
184293

185294
// Read source file then write atomically with PutMode::Create. Note that a GET/PUT is not
186295
// necessarily atomic, but since the source file is immutable, we aren't exposed to the
187296
// possiblilty of source file changing while we do the PUT.
188-
self.task_executor.block_on(async move {
297+
let result = self.task_executor.block_on(async move {
189298
let data = store.get(&src_path).await?.bytes().await?;
190299

191300
store
@@ -198,7 +307,17 @@ impl<E: TaskExecutor> StorageHandler for ObjectStoreStorageHandler<E> {
198307
e => e.into(),
199308
})?;
200309
Ok(())
201-
})
310+
});
311+
312+
if result.is_ok() {
313+
if let Some(ref r) = reporter {
314+
r.report(MetricEvent::StorageCopyCompleted {
315+
duration: timer.elapsed(),
316+
});
317+
}
318+
}
319+
320+
result
202321
}
203322
}
204323

@@ -243,7 +362,7 @@ mod tests {
243362

244363
let store = Arc::new(LocalFileSystem::new());
245364
let executor = Arc::new(TokioBackgroundExecutor::new());
246-
let storage = ObjectStoreStorageHandler::new(store, executor);
365+
let storage = ObjectStoreStorageHandler::new(store, executor, None);
247366

248367
let mut slices: Vec<FileSlice> = Vec::new();
249368

@@ -274,7 +393,7 @@ mod tests {
274393
store.put(&name, data.clone().into()).await.unwrap();
275394

276395
let table_root = Url::parse("memory:///").expect("valid url");
277-
let engine = DefaultEngine::new(store, Arc::new(TokioBackgroundExecutor::new()));
396+
let engine = DefaultEngine::new(store, Arc::new(TokioBackgroundExecutor::new()), None);
278397
let files: Vec<_> = engine
279398
.storage_handler()
280399
.list_from(&table_root.join("_delta_log").unwrap().join("0").unwrap())
@@ -304,7 +423,7 @@ mod tests {
304423

305424
let url = Url::from_directory_path(tmp.path()).unwrap();
306425
let store = Arc::new(LocalFileSystem::new());
307-
let engine = DefaultEngine::new(store, Arc::new(TokioBackgroundExecutor::new()));
426+
let engine = DefaultEngine::new(store, Arc::new(TokioBackgroundExecutor::new()), None);
308427
let files = engine
309428
.storage_handler()
310429
.list_from(&url.join("_delta_log").unwrap().join("0").unwrap())
@@ -331,7 +450,7 @@ mod tests {
331450
let tmp = tempfile::tempdir().unwrap();
332451
let store = Arc::new(LocalFileSystem::new());
333452
let executor = Arc::new(TokioBackgroundExecutor::new());
334-
let handler = ObjectStoreStorageHandler::new(store.clone(), executor);
453+
let handler = ObjectStoreStorageHandler::new(store.clone(), executor, None);
335454

336455
// basic
337456
let data = Bytes::from("test-data");

0 commit comments

Comments
 (0)