private void StabilizeFromSuccessor(StabilizeReply reply)
            {
                _node.Log($"StabilizeFromSuccessor");
                _node.Predecessor = reply.Predecessor;
                _node.SuccessorTable.Copy(reply.SuccessorTableEntries);

                _commMgr.SendInternal(new InitRectify());
            }
예제 #2
0
        protected Node(NodeInfo identity, NodeConfiguration config)
        {
            Config      = config;
            Identity    = identity;
            Predecessor = Identity;

            Clock = Config.Clock;
            CorrelationFactory = Config.CorrelationFactory;
            Janitor            = new DisposableStack();
            MessageBus         = new MemoryBus();
            Poller             = Janitor.Push(new NetMQPoller());
            Logger             = Config.LoggerDelegate;
            Marshaller         = Config.MarshallerFactory.Create();

            ExpiryCalculator = Config.ExpiryCalculator;

            Log($"Binding to {Config.NodeSocketFactory.BindingConnectionString(Identity.HostAndPort)}");
            ListeningSocket   = Janitor.Push(Config.NodeSocketFactory.CreateBindingSocket(Identity.HostAndPort));
            ForwardingSockets = Janitor.Push(new SocketCache(Config.NodeSocketFactory, Clock)); // Chicken and egg scenario where we require an actor!

            CommunicationManager = config.CommunicationManagerFactory.Create(Identity, Marshaller, ForwardingSockets, MessageBus, Log);

            Actor = Janitor.Push(CreateActor());
            ForwardingSockets.AddActor(Identity.HostAndPort, Actor);

            Janitor.Push(new DisposableAction(() => { Poller.Remove(ListeningSocket); }));
            Janitor.Push(new DisposableAction(
                             () => { ListeningSocket.ReceiveReady += ListeningSocketReceiveReady; },
                             () => { ListeningSocket.ReceiveReady -= ListeningSocketReceiveReady; }));

            ActionScheduler = Janitor.Push(new NodeActionScheduler(Clock, Config.ActionTimerFactory.Create(), Marshaller, Actor));
            MessageBus.Subscribe(new NodeHandler(this, ActionScheduler));
            var awaitHandler = Janitor.Push(new AwaitAckHandler(ActionScheduler, ExpiryCalculator, Marshaller, Actor, Log, Config.AwaitSettings));

            MessageBus.Subscribe(awaitHandler);
            MessageBus.Subscribe(new JoinNetworkHandler(this, CommunicationManager));
            MessageBus.Subscribe(new StabilizeHandler(this, CommunicationManager));
            MessageBus.Subscribe(new RectifyHandler(this, CommunicationManager));
            MessageBus.Subscribe(new NotifyHandler(this, CommunicationManager));

            FingerTable    = new FingerTable(Identity, Identity.RoutingHash.BitCount);
            SuccessorTable = new SuccessorTable(Identity, Config.SuccessorCount);

            // Let everything know we're ready to go.
            CommunicationManager.SendInternal(new NodeInitialised());
        }
            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);
            }