From 1d606e1cf6843e92b89f484b934516e2a42faec9 Mon Sep 17 00:00:00 2001 From: houseme Date: Mon, 31 Aug 2026 13:32:46 +0800 Subject: [PATCH] perf(ecstore): retry degraded GET with late parity (#6933) Co-authored-by: heihutu --- .../src/set_disk/core/io_primitives.rs | 20 +++++++++++++++++-- crates/ecstore/src/set_disk/ops/object.rs | 8 ++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/crates/ecstore/src/set_disk/core/io_primitives.rs b/crates/ecstore/src/set_disk/core/io_primitives.rs index 282bc926f..c79bd6868 100644 --- a/crates/ecstore/src/set_disk/core/io_primitives.rs +++ b/crates/ecstore/src/set_disk/core/io_primitives.rs @@ -453,6 +453,22 @@ use tokio::io::{AsyncRead, ReadBuf}; use tokio::sync::{Mutex, RwLock, oneshot}; use tokio::task::JoinSet; +struct AbortOnDropJoinHandle(tokio::task::JoinHandle); + +impl Future for AbortOnDropJoinHandle { + type Output = std::result::Result; + + fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { + Pin::new(&mut self.0).poll(cx) + } +} + +impl Drop for AbortOnDropJoinHandle { + fn drop(&mut self) { + self.0.abort(); + } +} + pub(in crate::set_disk) const EVENT_SET_DISK_READ: &str = "set_disk_read"; pub(in crate::set_disk) const ENV_RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP: &str = "RUSTFS_GET_DATA_BLOCKS_FIRST_READER_SETUP"; const ENV_RUSTFS_GET_METADATA_READ_VERSION_COALESCE: &str = "RUSTFS_GET_METADATA_READ_VERSION_COALESCE"; @@ -3008,7 +3024,7 @@ impl SetDisks { let object = object.clone(); let version_id = version_id.clone(); let slowtail_fault = slowtail_fault.clone(); - tokio::spawn(async move { + AbortOnDropJoinHandle(tokio::spawn(async move { let response_start = observe.then(Instant::now); let result = if let Some(disk) = disk { Self::record_read_version_call(&object, disk_index); @@ -3023,7 +3039,7 @@ impl SetDisks { }; let elapsed = response_start.map(|start| start.elapsed()); (result, elapsed) - }) + })) }); // Wait for all futures to complete diff --git a/crates/ecstore/src/set_disk/ops/object.rs b/crates/ecstore/src/set_disk/ops/object.rs index 0cf6b1b3a..0e2f27178 100644 --- a/crates/ecstore/src/set_disk/ops/object.rs +++ b/crates/ecstore/src/set_disk/ops/object.rs @@ -1442,6 +1442,14 @@ mod data_read_metadata_early_stop_request_shape_tests { restore_opts.transition.restore_request.days = Some(1); assert!(!data_read_metadata_early_stop_request_shape_allowed(&None, &restore_opts)); } + + #[test] + fn late_materialized_retry_clears_partial_buffer_after_error() { + let mut output = b"partial-prefix".to_vec(); + let result = Err(Error::FileCorrupt); + assert!(prepare_late_materialized_retry(&result, &mut output, 1024)); + assert!(output.is_empty()); + } } /// Length of the full plaintext body when — and only when — this read's output