master: echo the allocation bound to connected servers on change

The bound was only sent at connect time or on digest mismatch, so a
healthy stream never learned later increases. If the high-id server then
went offline and the master lost state, survivors restored a stale bound
and the id could be reissued. Resend the heartbeat response whenever the
bound or topology id moved.
This commit is contained in:
Chris Lu
2026-10-19 03:09:25 -07:00
parent 67c92e3f5a
commit a03b3e6133
+15
View File
@@ -139,6 +139,8 @@ func (ms *MasterServer) SendHeartbeat(stream master_pb.Seaweed_SendHeartbeatServ
}
}()
var echoedVid needle.VolumeId
var echoedTopoId string
for {
heartbeat, err := stream.Recv()
if err != nil {
@@ -209,6 +211,7 @@ func (ms *MasterServer) SendHeartbeat(stream master_pb.Seaweed_SendHeartbeatServ
glog.Warningf("SendHeartbeat.Send volume size to %s:%d %v", dn.Ip, dn.Port, err)
return err
}
echoedVid, echoedTopoId = ms.Topo.GetMaxVolumeId(), ms.Topo.GetTopologyId()
stats.MasterReceivedHeartbeatCounter.WithLabelValues("dataNode").Inc()
dn.Counter++
}
@@ -345,6 +348,18 @@ func (ms *MasterServer) SendHeartbeat(stream master_pb.Seaweed_SendHeartbeatServ
glog.Warningf("SendHeartbeat.Send resend request to %s:%d %v", dn.Ip, dn.Port, err)
return err
}
echoedVid, echoedTopoId = ms.Topo.GetMaxVolumeId(), ms.Topo.GetTopologyId()
}
// Every connected server keeps a durable copy of the bound. Echo it
// whenever it moved so one veteran can restore it after state loss,
// even while the offline server that held the high ids never rejoins.
if vid, topoId := ms.Topo.GetMaxVolumeId(), ms.Topo.GetTopologyId(); vid != echoedVid || topoId != echoedTopoId {
if err := stream.Send(ms.heartbeatResponse()); err != nil {
glog.Warningf("SendHeartbeat.Send bound echo %v", err)
return err
}
echoedVid, echoedTopoId = vid, topoId
}
}
}