public void Handle(InitRectify message) { _node.LogMessage(message); // Notify the successor to update it's predecessor with this node's info var opId = _node.Config.CorrelationFactory.GetNextCorrelation(); var handler = _node.CreateAwaitAllResponsesHandler(); handler .PerformAction(() => { _node.Log($"Sending Rectify to {_node.Successor} Id:{opId}"); var msg = new Rectify(_node.Identity, _node.Successor, opId) { Predecessor = _node.Identity }; _commMgr.Send(msg); }) .AndAwait(opId, (RectifyReply reply) => { _node.LogMessage(reply); _node.Log($"{_node.Identity} Joined Network"); }) .Run(opId); }
private void JoinToSeed(NodeInfo seedNodeInfo) { _node.Predecessor = _node.Identity; _node.FingerTable.Init(); var opId = _node.Config.CorrelationFactory.GetNextCorrelation(); var startTime = _node.Clock.Now; var responseHandler = _node.CreateAwaitAllResponsesHandler(); responseHandler .PerformAction(() => { var msg = new JoinNetwork(_node.Identity, seedNodeInfo, opId) { RoutingTable = _node.FingerTable.Entries, }; _node.Log($"Sending {msg.TypeName()} To {seedNodeInfo} Id:{opId}"); _commMgr.Send(msg); }) .AndAwait(opId, (JoinNetworkReply reply) => { _node.Log($"{reply.TypeName()} From {reply.From} Id:{reply.CorrelationId}"); _node.Log($"Join took {(_node.Clock.Now - startTime).Milliseconds} ms"); _node.Log($"Assigning successor {reply.SuccessorTable[0].SuccessorIdentity}"); _node.SuccessorTable.Copy(reply.SuccessorTable); //_node.FingerTable.Copy(reply.RoutingTable); // This node has "joined" but is not in an ideal state as it is not part of the ring network yet. }) .ContinueWith(() => { _commMgr.SendInternal(new InitStabilize()); }) .Run(opId); }
private void Stabilize(NodeInfo successorInfo) { // Send a stabilize message to my successor to learn it's predecessor // Stabilize might need to be retried as other nodes will be joining at the same location as it is a seed node. var opId = _node.Config.CorrelationFactory.GetNextCorrelation(); var messageHandler = _node.CreateAwaitAllResponsesHandler(); messageHandler .PerformAction(() => { var msg = new Stabilize(_node.Identity, successorInfo, opId); _node.Log($"Sending {msg.TypeName()} To:{msg.To} Id:{opId}"); _commMgr.Send(msg); }) .AndAwait(opId, (StabilizeReply reply) => { var thisHash = _node.Identity.RoutingHash; var predecessorHash = reply.Predecessor.RoutingHash; var successorHash = successorInfo.RoutingHash; // We need to check the order of the predecessor or the successor before adopting a value // as nodes are racing to join the seed node - our last query may be out of date, but not by much if (thisHash.IsBetween(predecessorHash, successorHash)) { // No ordering change. We can adopt the predecessor values and tell the successor to rectify StabilizeFromSuccessor(reply); } else if (predecessorHash.IsBetween(thisHash, successorHash)) { // another node beat this one to join to the successor, changing the ordering... StabilizeFromPredecessor(reply); } }) .Run(opId); }
public void Handle(Notify message) { _node.Log($"{message.TypeName()} From:{message.From}"); _commMgr.SendAck(message, message.CorrelationId); // Let the predecessor know to join to the specified successor. // And adjust successor table accordingly. var entries = _node.SuccessorTable.Entries; for (int i = 1; i < entries.Length; ++i) { entries[i] = entries[i - 1]; } var successor = message.NewSuccessor; entries[0] = new RoutingTableEntry(successor.RoutingHash, successor); _node.Log($"Changed successor to {successor}"); _commMgr.Send(new NotifyReply(_node.Identity, message.From, message.CorrelationId)); }