private void StabilizeFromSuccessor(StabilizeReply reply) { _node.Log($"StabilizeFromSuccessor"); _node.Predecessor = reply.Predecessor; _node.SuccessorTable.Copy(reply.SuccessorTableEntries); _commMgr.SendInternal(new InitRectify()); }
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); }