Ejemplo n.º 1
0
            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);
                //        }
                //    });
            }
Ejemplo n.º 2
0
            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(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);
                }
            }
Ejemplo n.º 4
0
            public void Handle(GetSuccessor message)
            {
                var responder = new RequestResponseHandler <Guid>(Node.MessageBus);

                Subscribe(responder);

                var remainingResponses = new Reference <int>(Node.SuccessorCount);



                if (message.SuccessorIndex >= 0)
                {
                    var nextSuccessorIndex = message.SuccessorIndex - 1;

                    // Forward to the next successor
                    var forwardMsg = new GetSuccessor(message.Identity, message.ForNode, GetNextCorrelation(), nextSuccessorIndex);
                    ForwardMessageTo(Node.Successor, forwardMsg); // trap a potential loop
                }

                // reply with this node information
            }
Ejemplo n.º 5
0
            public void Handle(Stabilize message)
            {
                Node.Logger?.Invoke($"{Node.Identity.Identifier} received Stabilize from {message.Identity}");
                // Get the predecessor of my current successor
                var theBus    = Node.MessageBus;
                var nextGuid  = Node.CorrelationFactory.GetNextCorrelation();
                var responder = new RequestResponseHandler <Guid>(theBus);

                theBus.Subscribe(responder);

                responder.Await(nextGuid,
                                (GetPredecessor.Reply reply) =>
                {
                    Node.Logger?.Invoke($"GetPredecessor reply from {Node.Successor}");
                    // If I am not the predecessor, the result is my new successor
                    //if (reply.Identity == null)
                    //{
                    //    Node.Predecessor = Node.Successor; // Close the loop
                    //}
                    //else
                    {
                        // If I am not the predecessor, the result is my new successor
                        if (reply.Identity != null && !Node.Identity.Equals(reply.Identity))
                        {
                            if (Node.IsIDInDomain(
                                    reply.Identity.RoutingHash,
                                    Node.Identity.RoutingHash,
                                    Node.Successor.RoutingHash))
                            {
                                Node.Successor = message.Identity;
                            }
                        }

                        //if (!Node.Identity.Equals(reply.Identity))
                        //{
                        //    Node.Logger?.Invoke($"{Node.Identity} assigning predecessor as {reply.Identity}");
                        //    Node.Predecessor = reply.Identity;
                        //}
                    }
                    // Send notify predecessor to my new successor
                    Node.Logger?.Invoke($"{Node.Identity} sending NotifyPredecessor to {Node.Successor}");
                    Node.ForwardMessageTo(Node.Successor, new NotifyPredecessor(Node.Identity));

                    //if (reply.Identity != null && !Node.Identity.Equals(reply.Identity))
                    //{
                    //    Node.Logger?.Invoke($"{Node.Identity} assigning successor as {reply.Identity}");
                    //    Node.Successor = reply.Identity;

                    //    // Send notify predecessor to my new successor
                    //    Node.Logger?.Invoke($"{Node.Identity} sending NotifyPredecessor to {Node.Successor}");
                    //    Node.ForwardMessageTo(Node.Successor, new NotifyPredecessor(Node.Identity));
                    //}
                    //else
                    //{
                    //    Node.Logger?.Invoke($"{Node.Identity} is stable. S({Node.Successor}) P({Node.Predecessor})");
                    //}
                    theBus.Unsubscribe(responder);
                });

                // Kick the whole sequence off
                Node.Logger?.Invoke($"Sending GetPredecessor request to {Node.Successor}");
                Node.ForwardMessageTo(Node.Successor, new GetPredecessor(Node.Identity, nextGuid));
            }
Ejemplo n.º 6
0
 protected void CloseHandlerWithReply(NodeReply replyMsg, NodeInfo replyTarget, RequestResponseHandler <Guid> responder = null)
 {
     SendReplyTo(replyTarget, replyMsg);
     if (responder != null)
     {
         Unsubscribe(responder);
     }
     CloseHandler();
 }
Ejemplo n.º 7
0
 protected void Unsubscribe(RequestResponseHandler <Guid> responder)
 {
     Node.MessageBus.Unsubscribe(responder);
 }