From 84d3d626979020289b89b822ee1dce41738553d3 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Mon, 27 Jul 2026 17:41:49 -0700 Subject: [PATCH] rust volume: mark-readonly notifies the live leader, not the static seed (#10461) VolumeMarkReadonly mutates raft-replicated master topology, so it must reach the leader. notify_master_volume_readonly targeted the static seed (config.masters.first()), so after any master failover it hit a follower and failed "not current leader". Prefer current_master_url (the live leader the heartbeat tracks), fall back to the seed before the first heartbeat, mirroring store_ec.rs and Go's vs.GetMaster(). Claude-Session: https://claude.ai/code/session_01Ks16jnt4S7gdDk8cheQ3xu --- seaweed-volume/src/server/grpc_server.rs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/seaweed-volume/src/server/grpc_server.rs b/seaweed-volume/src/server/grpc_server.rs index c695ddcb1..1b335ed57 100644 --- a/seaweed-volume/src/server/grpc_server.rs +++ b/seaweed-volume/src/server/grpc_server.rs @@ -182,7 +182,19 @@ impl VolumeGrpcService { info: &MasterVolumeInfo, is_readonly: bool, ) -> Result<(), Status> { - let master_url = self.state.master_url.clone(); + // VolumeMarkReadonly mutates raft-replicated master topology, so it must + // reach the leader. Prefer the live leader the heartbeat is talking to + // (current_master_url), falling back to the static seed before the first + // heartbeat — mirrors store_ec.rs and Go's vs.GetMaster(). Sending it to + // the static seed fails "not current leader" after any master failover. + let master_url = { + let live = self.state.current_master_url.read().await.clone(); + if !live.is_empty() { + live + } else { + self.state.master_url.clone() + } + }; if master_url.is_empty() { return Ok(()); }