You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

64 lines
2.0 KiB

package weed_server
import (
"encoding/json"
"time"
"github.com/google/uuid"
"github.com/seaweedfs/seaweedfs/weed/glog"
"github.com/seaweedfs/seaweedfs/weed/topology"
)
// recoverTopologyIdFromState restores the TopologyId from serialized FSM
// state bytes (JSON-encoded MaxVolumeIdCommand). Both raft implementations
// call this after reading their snapshot in their own format.
func recoverTopologyIdFromState(fsmState []byte, topo *topology.Topology) {
if topo.GetTopologyId() != "" {
return
}
var cmd topology.MaxVolumeIdCommand
if err := json.Unmarshal(fsmState, &cmd); err != nil {
return
}
if cmd.TopologyId != "" {
topo.SetTopologyId(cmd.TopologyId)
glog.V(0).Infof("Recovered TopologyId from snapshot: %s", cmd.TopologyId)
}
}
// EnsureTopologyId ensures that a TopologyId is generated and persisted if it's currently missing.
// It uses the provided checkLeaderFn to verify leadership and persistFn to save the new ID.
func EnsureTopologyId(topo *topology.Topology, checkLeaderFn func() bool, persistFn func(string) error) {
if topo.GetTopologyId() != "" {
return
}
topologyId := uuid.New().String()
for {
if !checkLeaderFn() {
glog.V(0).Infof("lost leadership while saving topologyId")
return
}
// Another concurrent operation may have set the ID between generation and now.
if latestId := topo.GetTopologyId(); latestId != "" {
glog.V(1).Infof("topologyId was set concurrently to %s, aborting generation", latestId)
return
}
if err := persistFn(topologyId); err != nil {
glog.Errorf("failed to save topologyId, will retry: %v", err)
time.Sleep(time.Second)
continue
}
// Verify that the topology ID was actually applied as expected.
appliedId := topo.GetTopologyId()
if appliedId != "" && appliedId != topologyId {
glog.V(0).Infof("TopologyId generation race: expected %s, but current TopologyId is %s", topologyId, appliedId)
} else {
glog.V(0).Infof("TopologyId generated: %s", topologyId)
}
break
}
}