Browse Source

Fix heartbeat: check leader != current master before redirect, process duplicated UUIDs first

Match Go's volume_grpc_client_to_master.go behavior:
1. Only trigger leader redirect when the leader address differs from the
   current master (prevents unnecessary reconnect loops when master confirms
   its own address).
2. Process duplicated_uuids before leader redirect check, matching Go's
   ordering where duplicate UUID detection takes priority.
rust-volume-server
Chris Lu 3 days ago
parent
commit
def1b0fb03
  1. 13
      seaweed-volume/src/server/heartbeat.rs

13
seaweed-volume/src/server/heartbeat.rs

@ -89,7 +89,7 @@ pub async fn run_heartbeat_with_state(
SleepDuplicate(Duration),
SleepPulse,
}
let action = match do_heartbeat(&config, &state, &grpc_addr, pulse, &mut shutdown_rx)
let action = match do_heartbeat(&config, &state, &grpc_addr, &target_addr, pulse, &mut shutdown_rx)
.await
{
Ok(Some(leader)) => {
@ -346,6 +346,7 @@ async fn do_heartbeat(
config: &HeartbeatConfig,
state: &Arc<VolumeServerState>,
grpc_addr: &str,
current_master: &str,
pulse: Duration,
shutdown_rx: &mut broadcast::Receiver<()>,
) -> Result<Option<String>, Box<dyn std::error::Error>> {
@ -428,9 +429,8 @@ async fn do_heartbeat(
if metrics_changed {
state.metrics_notify.notify_waiters();
}
if !hb_resp.leader.is_empty() {
return Ok(Some(hb_resp.leader));
}
// Match Go ordering: check duplicated_uuids BEFORE leader redirect.
// Go processes DuplicatedUuids first, then volume options, then leader.
if !hb_resp.duplicated_uuids.is_empty() {
let duplicate_dirs = {
let store = state.store.read().unwrap();
@ -446,6 +446,11 @@ async fn do_heartbeat(
)
.into());
}
// Match Go: only redirect if leader is non-empty AND
// different from the current master we're connected to.
if !hb_resp.leader.is_empty() && current_master != hb_resp.leader {
return Ok(Some(hb_resp.leader));
}
}
Ok(None) => return Ok(None),
Err(e) => return Err(Box::new(e)),

Loading…
Cancel
Save