From 7451c593efbe7de4214bf372d7095217e8bbc647 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Wed, 18 Mar 2026 11:44:49 -0700 Subject: [PATCH] fix FetchAndWriteNeedle to await all writes before checking errors Go uses a WaitGroup to await all writes (local + replicas) before checking errors. Rust was short-circuiting on local write failure, which could leave replica writes in-flight without waiting for completion. --- seaweed-volume/src/server/grpc_server.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/seaweed-volume/src/server/grpc_server.rs b/seaweed-volume/src/server/grpc_server.rs index ef35e5dce..594ea1c09 100644 --- a/seaweed-volume/src/server/grpc_server.rs +++ b/seaweed-volume/src/server/grpc_server.rs @@ -3220,8 +3220,15 @@ impl VolumeServer for VolumeGrpcService { } } - // Await local write - match local_handle.await { + // Await ALL writes before checking errors (matches Go's wg.Wait()) + let local_result = local_handle.await; + let mut replica_results = Vec::new(); + for handle in handles { + replica_results.push(handle.await); + } + + // Check local write result + match local_result { Ok(Ok(())) => {} Ok(Err(e)) => return Err(Status::internal(e)), Err(e) => return Err(Status::internal(format!("local write task failed: {}", e))), @@ -3229,9 +3236,9 @@ impl VolumeServer for VolumeGrpcService { let e_tag = n.etag(); - // Await replica writes - for handle in handles { - match handle.await { + // Check replica write results + for result in replica_results { + match result { Ok(Ok(())) => {} Ok(Err(e)) => return Err(Status::internal(e)), Err(e) => return Err(Status::internal(format!("replication task failed: {}", e))),