public void Handle(GetFingerTable message) { var bitCount = message.Identity.RoutingHash.BitCount; var entries = FingerTable.CreateEntries(bitCount, message.ForNode.RoutingHash); var responder = new RequestResponseHandler <Guid>(Node.MessageBus); Node.MessageBus.Subscribe(responder); var replyCount = new Reference <int>(0); // ensure all replies share the current count for (int i = 0; i < bitCount; ++i) { var index = i; // Value must be constant in the scope of the reply responder.Publish( new FindSuccessorToHash(Node.Identity, entries[i].StartValue, GetNextCorrelation()), (FindSuccessorToHash.Reply reply) => { entries[index] = new RoutingTableEntry(entries[index].StartValue, reply.Successor); ++replyCount.Value; if (replyCount == bitCount) { var getFingerTableReply = new GetFingerTable.Reply(Node.Identity, message.CorrelationId, entries); CloseHandlerWithReply(getFingerTableReply, message.Identity, responder); } }); } }
public void Handle(JoinNetwork message) { // acquire the necessary information for a node sending this message // It may only be correct for a short time if lots of nodes are joining at roughly the same time. var responder = new RequestResponseHandler <Guid>(Node.MessageBus); Node.MessageBus.Subscribe(responder); var joinNetworkReply = new JoinNetwork.Reply(message.Identity, message.CorrelationId); responder.Publish( new GetFingerTable(Node.Identity, message.Identity, GetNextCorrelation()), (GetFingerTable.Reply reply) => { joinNetworkReply.RoutingTableEntries = reply.RoutingTableEntries; if (joinNetworkReply.IsReadyToTransmit) { CloseHandlerWithReply(joinNetworkReply, joinNetworkReply.Identity, responder); } }); // TODO: Multiple successors //responder.Publish( // new GetSuccessor(Node.Identity, message.Identity, GetNextCorrelation()), // (GetSuccessor.Reply reply) => // { // joinNetworkReply.SuccessorList = reply.SuccessorList; // if (joinNetworkReply.IsReadyToTransmit) // { // CloseHandlerWithReply(joinNetworkReply, joinNetworkReply.Identity, responder); // } // }); }
public void Handle(FindSuccessorToHash message) { if (Node.IsInDomain(message.ToHash)) { var msg = new FindSuccessorToHash.Reply(message.Identity, Node.Identity, message.CorrelationId); CloseHandlerWithReply(msg, message.Identity); } else { var newCorrelation = Node.CorrelationFactory.GetNextCorrelation(); var responder = new RequestResponseHandler <Guid>(Node.MessageBus); Node.MessageBus.Subscribe(responder); responder.Publish( new FindSuccessorToHash.Await(newCorrelation), (FindSuccessorToHash.Reply networkReply) => { // Forward the reply to the original sender with the initial correlation. var msg = new FindSuccessorToHash.Reply(message.Identity, networkReply.Successor, message.CorrelationId); CloseHandlerWithReply(msg, message.Identity, responder); }); // Forward a new query to another node and reply back to this node. var startValue = message.ToHash; var forwardMsg = new FindSuccessorToHash(Node.Identity, startValue, newCorrelation); var closestNode = Node.FindClosestPrecedingFinger(startValue); var forwardingSocket = Node.ForwardingSockets[closestNode.HostAndPort]; Node.Marshaller.Send(forwardMsg, forwardingSocket); } }