From a18d6d9ae3e1f395042eed39f06685dcaeb2ecc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arpad=20M=C3=BCller?= Date: Mon, 11 Sep 2023 18:41:08 +0200 Subject: [PATCH] Make File opening in VirtualFile async-compatible (#5280) ## Problem Previously, we were using `observe_closure_duration` in `VirtualFile` file opening code, but this doesn't support async open operations, which we want to use as part of #4743. ## Summary of changes * Move the duration measurement from the `with_file` macro into a `observe_duration` macro. * Some smaller drive-by fixes to replace the old strings with the new variant names introduced by #5273 Part of #4743, follow-up of #5247. --- pageserver/src/virtual_file.rs | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/pageserver/src/virtual_file.rs b/pageserver/src/virtual_file.rs index 5dc7e4e490..e437ffb2d7 100644 --- a/pageserver/src/virtual_file.rs +++ b/pageserver/src/virtual_file.rs @@ -154,7 +154,7 @@ impl OpenFiles { // old file. // if let Some(old_file) = slot_guard.file.take() { - // the normal path of dropping VirtualFile uses "close", use "close-by-replace" here to + // the normal path of dropping VirtualFile uses `Close`, use `CloseByReplace` here to // distinguish the two. STORAGE_IO_TIME_METRIC .get(StorageIoOperation::CloseByReplace) @@ -209,9 +209,12 @@ impl CrashsafeOverwriteError { } } -macro_rules! with_file { - ($this:expr, $op:expr, | $ident:ident | $($body:tt)*) => {{ - let $ident = $this.lock_file().await?; +/// Observe duration for the given storage I/O operation +/// +/// Unlike `observe_closure_duration`, this supports async, +/// where "support" means that we measure wall clock time. +macro_rules! observe_duration { + ($op:expr, $($body:tt)*) => {{ let instant = Instant::now(); let result = $($body)*; let elapsed = instant.elapsed().as_secs_f64(); @@ -219,6 +222,13 @@ macro_rules! with_file { .get($op) .observe(elapsed); result + }} +} + +macro_rules! with_file { + ($this:expr, $op:expr, | $ident:ident | $($body:tt)*) => {{ + let $ident = $this.lock_file().await?; + observe_duration!($op, $($body)*) }}; } @@ -260,9 +270,7 @@ impl VirtualFile { } let (handle, mut slot_guard) = get_open_files().find_victim_slot().await; - let file = STORAGE_IO_TIME_METRIC - .get(StorageIoOperation::Open) - .observe_closure_duration(|| open_options.open(path))?; + let file = observe_duration!(StorageIoOperation::Open, open_options.open(path))?; // Strip all options other than read and write. // @@ -405,9 +413,7 @@ impl VirtualFile { let (handle, mut slot_guard) = open_files.find_victim_slot().await; // Open the physical file - let file = STORAGE_IO_TIME_METRIC - .get(StorageIoOperation::Open) - .observe_closure_duration(|| self.open_options.open(&self.path))?; + let file = observe_duration!(StorageIoOperation::Open, self.open_options.open(&self.path))?; // Store the File in the slot and update the handle in the VirtualFile // to point to it. @@ -595,7 +601,7 @@ impl Drop for VirtualFile { fn clean_slot(slot: &Slot, mut slot_guard: RwLockWriteGuard<'_, SlotInner>, tag: u64) { if slot_guard.tag == tag { slot.recently_used.store(false, Ordering::Relaxed); - // there is also operation "close-by-replace" for closes done on eviction for + // there is also the `CloseByReplace` operation for closes done on eviction for // comparison. STORAGE_IO_TIME_METRIC .get(StorageIoOperation::Close)