protected Node(NodeInfo identity, NodeConfiguration config) { Logger = config.LoggerDelegate; SeedNode = config.SeedNode; SuccessorCount = config.SuccessorCount; Serializer = config.Serializer; Marshaller = new NodeMarshaller(Serializer, config.HashingService); MessageBus = new MemoryBus(); // We can change the publishing strategy factory so we can log everything... InitHandlers(); Identity = identity; Successor = identity; Predecessor = null; SocketFactory = config.NodeSocketFactory; HashingService = config.HashingService; CorrelationFactory = config.CorrelationFactory; Clock = config.Clock; Janitor = new DisposableStack(); Poller = Janitor.Push(new NetMQPoller()); InitTimer = CreateInitTimer(); ListeningSocket = Janitor.Push(SocketFactory.CreateBindingSocket(Identity.HostAndPort)); InitListeningSocket(); ForwardingSockets = Janitor.Push(new SocketCache(SocketFactory, Clock)); Actor = Janitor.Push(CreateActor()); InitTimer.Elapsed += (sender, args) => { Publish(new NodeReady(Identity.RoutingHash)); }; FingerTable = new FingerTable(Identity, Identity.RoutingHash.BitCount); SuccessorTable = new SuccessorTable(Identity, config.SuccessorCount); }
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); } }); } }
private NodeInfo FindClosestPrecedingFinger(ConsistentHash toNode) { return(FingerTable.FindClosestPrecedingFinger(toNode)); }