From c4e0ba38b8b89807b177381803b0195c9d107aba Mon Sep 17 00:00:00 2001 From: Christian Schwarz Date: Tue, 21 Jan 2025 19:33:13 +0100 Subject: [PATCH] drain spawned IOs if traversal fails; https://github.com/neondatabase/neon/pull/9353/files#r1923589380 --- pageserver/src/tenant/timeline.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pageserver/src/tenant/timeline.rs b/pageserver/src/tenant/timeline.rs index e83d45ef98..c881de5dfe 100644 --- a/pageserver/src/tenant/timeline.rs +++ b/pageserver/src/tenant/timeline.rs @@ -1172,8 +1172,19 @@ impl Timeline { let get_data_timer = crate::metrics::GET_RECONSTRUCT_DATA_TIME .for_get_kind(get_kind) .start_timer(); - self.get_vectored_reconstruct_data(keyspace.clone(), lsn, reconstruct_state, ctx) - .await?; + let traversal_res: Result<(), _> = self + .get_vectored_reconstruct_data(keyspace.clone(), lsn, reconstruct_state, ctx) + .await; + if let Err(err) = traversal_res { + // Wait for all the spawned IOs to complete. + // See comments on `spawn_io` inside `storage_layer` for more details. + let mut collect_futs = std::mem::take(&mut reconstruct_state.keys) + .into_values() + .map(|state| state.collect_pending_ios()) + .collect::>(); + while collect_futs.next().await.is_some() {} + return Err(err); + }; get_data_timer.stop_and_record(); let reconstruct_timer = crate::metrics::RECONSTRUCT_TIME