fix cluster: hashRing stale after rebalance, GetShardMap empty, loops, and migration no-op
- GetShardMap: copy Shards and Nodes map contents before returning - hashRing: rebuild from shardMap.Nodes after every rebalance/shard_map update - DistributedVM.handleRebalanceRequest: add leader check and self-broadcast guard - route_message: add hop-count (MaxRouteHops=10) to prevent infinite loops - handleMigrationRequest: broadcast migration updates instead of setting local copy
This commit is contained in:
@@ -150,6 +150,15 @@ func (dvm *DistributedVM) SendMessage(message RuntimeMessage) error {
|
||||
|
||||
// routeMessageToNode sends a message to another node for delivery to the target actor
|
||||
func (dvm *DistributedVM) routeMessageToNode(actorID string, message RuntimeMessage) error {
|
||||
hops := 0
|
||||
if mp, ok := message.(*MessagePayload); ok {
|
||||
hops = mp.Hops
|
||||
}
|
||||
if hops >= MaxRouteHops {
|
||||
dvm.cluster.logger.Printf("Dropping message for actor %s: exceeded max hops (%d)", actorID, MaxRouteHops)
|
||||
return fmt.Errorf("message exceeded max hops")
|
||||
}
|
||||
|
||||
msg := ClusterMessage{
|
||||
Type: "route_message",
|
||||
From: dvm.nodeID,
|
||||
@@ -157,6 +166,7 @@ func (dvm *DistributedVM) routeMessageToNode(actorID string, message RuntimeMess
|
||||
Payload: MessagePayload{
|
||||
TargetActorID: actorID,
|
||||
Type: message.GetType(),
|
||||
Hops: hops + 1,
|
||||
},
|
||||
Timestamp: time.Now(),
|
||||
}
|
||||
@@ -220,6 +230,11 @@ func (dvm *DistributedVM) handleClusterMessage(msg *nats.Msg) {
|
||||
return
|
||||
}
|
||||
|
||||
if message.Hops >= MaxRouteHops {
|
||||
dvm.cluster.logger.Printf("Dropping message for actor %s: exceeded max hops (%d)", message.TargetActorID, MaxRouteHops)
|
||||
return
|
||||
}
|
||||
|
||||
targetActor := message.TargetActorID
|
||||
if dvm.IsLocalActor(targetActor) {
|
||||
dvm.localRuntime.SendMessage(&message)
|
||||
@@ -236,6 +251,15 @@ func (dvm *DistributedVM) handleClusterMessage(msg *nats.Msg) {
|
||||
|
||||
// handleRebalanceRequest processes shard rebalancing requests
|
||||
func (dvm *DistributedVM) handleRebalanceRequest(msg ClusterMessage) {
|
||||
if msg.From == dvm.nodeID {
|
||||
return
|
||||
}
|
||||
|
||||
if !dvm.cluster.IsLeader() {
|
||||
dvm.cluster.logger.Printf("Ignoring rebalance request: not the leader")
|
||||
return
|
||||
}
|
||||
|
||||
payloadBytes, err := json.Marshal(msg.Payload)
|
||||
if err != nil {
|
||||
dvm.cluster.logger.Printf("Failed to marshal rebalance payload: %v", err)
|
||||
@@ -251,6 +275,10 @@ func (dvm *DistributedVM) handleRebalanceRequest(msg ClusterMessage) {
|
||||
dvm.cluster.mutex.Lock()
|
||||
if newShardMap.Version > dvm.cluster.shardMap.Version {
|
||||
dvm.cluster.shardMap = &newShardMap
|
||||
dvm.cluster.hashRing = NewConsistentHashRing()
|
||||
for nodeID := range newShardMap.Nodes {
|
||||
dvm.cluster.hashRing.AddNode(nodeID)
|
||||
}
|
||||
dvm.cluster.logger.Printf("Applied new shard map (version %d) from rebalance", newShardMap.Version)
|
||||
} else {
|
||||
dvm.cluster.logger.Printf("Ignoring stale shard map (got version %d, current %d)",
|
||||
|
||||
Reference in New Issue
Block a user