예제 #1
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);
                        }
                    });
                }
            }
예제 #2
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);
                //        }
                //    });
            }
            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);
                }
            }