コード例 #1
0
        public NodeGossipService(IPublisher bus,
                                 IGossipSeedSource gossipSeedSource,
                                 VNodeInfo nodeInfo,
                                 ICheckpoint writerCheckpoint,
                                 ICheckpoint chaserCheckpoint,
                                 IEpochManager epochManager,
                                 Func <long> getLastCommitPosition,
                                 int nodePriority,
                                 TimeSpan gossipInterval,
                                 TimeSpan allowedTimeDifference,
                                 TimeSpan gossipTimeout,
                                 TimeSpan deadMemberRemovalPeriod,
                                 ITimeProvider timeProvider,
                                 Func <MemberInfo[], MemberInfo> getNodeToGossipTo = null)
            : base(bus, gossipSeedSource, nodeInfo, gossipInterval, allowedTimeDifference, gossipTimeout, deadMemberRemovalPeriod, timeProvider, getNodeToGossipTo)
        {
            Ensure.NotNull(writerCheckpoint, nameof(writerCheckpoint));
            Ensure.NotNull(chaserCheckpoint, nameof(chaserCheckpoint));
            Ensure.NotNull(epochManager, nameof(epochManager));
            Ensure.NotNull(getLastCommitPosition, nameof(getLastCommitPosition));

            _writerCheckpoint      = writerCheckpoint;
            _chaserCheckpoint      = chaserCheckpoint;
            _epochManager          = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority          = nodePriority;
            _timeProvider          = timeProvider;
        }
コード例 #2
0
        public ReplicaService(IPublisher publisher,
                              TFChunkDb db,
                              IEpochManager epochManager,
                              IPublisher networkSendQueue,
                              IAuthenticationProvider authProvider,
                              VNodeInfo nodeInfo,
                              bool useSsl,
                              string sslTargetHost,
                              bool sslValidateServer)
        {
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(networkSendQueue, "networkSendQueue");
            Ensure.NotNull(authProvider, "authProvider");
            Ensure.NotNull(nodeInfo, "nodeInfo");
            if (useSsl)
            {
                Ensure.NotNull(sslTargetHost, "sslTargetHost");
            }

            _publisher        = publisher;
            _db               = db;
            _epochManager     = epochManager;
            _networkSendQueue = networkSendQueue;
            _authProvider     = authProvider;

            _nodeInfo          = nodeInfo;
            _useSsl            = useSsl;
            _sslTargetHost     = sslTargetHost;
            _sslValidateServer = sslValidateServer;

            _connector = new TcpClientConnector();
        }
コード例 #3
0
        public override async Task TestFixtureSetUp()
        {
            await base.TestFixtureSetUp();

            Db = new TFChunkDb(CreateDbConfig());
            Db.Open();
            Chaser = new TFChunkChaser(Db, _writerChk, _chaserChk, false);
            Chaser.Open();
            Writer = new TFChunkWriter(Db);
            Writer.Open();

            IndexCommitter = new FakeIndexCommitterService();
            EpochManager   = new FakeEpochManager();

            Service = new StorageChaser(
                Publisher,
                _writerChk,
                Chaser,
                IndexCommitter,
                EpochManager,
                new QueueStatsManager());

            Service.Handle(new SystemMessage.SystemStart());
            Service.Handle(new SystemMessage.SystemInit());

            Publisher.Subscribe(new AdHocHandler <StorageMessage.CommitAck>(CommitAcks.Enqueue));
            Publisher.Subscribe(new AdHocHandler <StorageMessage.PrepareAck>(PrepareAcks.Enqueue));

            When();
        }
コード例 #4
0
        public MasterReplicationService(IPublisher publisher,
                                        Guid instanceId,
                                        TFChunkDb db,
                                        IPublisher tcpSendPublisher,
                                        IEpochManager epochManager,
                                        int clusterSize)
        {
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotEmptyGuid(instanceId, "instanceId");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(tcpSendPublisher, "tcpSendPublisher");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.Positive(clusterSize, "clusterSize");

            _publisher        = publisher;
            _instanceId       = instanceId;
            _db               = db;
            _tcpSendPublisher = tcpSendPublisher;
            _epochManager     = epochManager;
            _clusterSize      = clusterSize;

            _lastRolesAssignmentTimestamp = _stopwatch.Elapsed;
            _mainLoopThread = new Thread(MainLoop)
            {
                Name = _queueStats.Name, IsBackground = true
            };
        }
コード例 #5
0
        public ElectionsService(IPublisher publisher,
                                MemberInfo memberInfo,
                                int clusterSize,
                                ICheckpoint writerCheckpoint,
                                ICheckpoint chaserCheckpoint,
                                IEpochManager epochManager,
                                Func <long> getLastCommitPosition,
                                int nodePriority,
                                ITimeProvider timeProvider)
        {
            Ensure.NotNull(publisher, nameof(publisher));
            Ensure.NotNull(memberInfo, nameof(memberInfo));
            Ensure.Positive(clusterSize, nameof(clusterSize));
            Ensure.NotNull(writerCheckpoint, nameof(writerCheckpoint));
            Ensure.NotNull(chaserCheckpoint, nameof(chaserCheckpoint));
            Ensure.NotNull(epochManager, nameof(epochManager));
            Ensure.NotNull(getLastCommitPosition, nameof(getLastCommitPosition));
            Ensure.NotNull(timeProvider, nameof(timeProvider));
            if (memberInfo.IsReadOnlyReplica)
            {
                throw new ArgumentException("Read-only replicas are not allowed to run the Elections service.");
            }

            _publisher             = publisher;
            _memberInfo            = memberInfo;
            _publisherEnvelope     = new PublishEnvelope(_publisher);
            _clusterSize           = clusterSize;
            _writerCheckpoint      = writerCheckpoint;
            _chaserCheckpoint      = chaserCheckpoint;
            _epochManager          = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority          = nodePriority;
            _timeProvider          = timeProvider;

            var ownInfo = GetOwnInfo();

            _servers = new[] {
                MemberInfo.ForVNode(memberInfo.InstanceId,
                                    _timeProvider.UtcNow,
                                    VNodeState.Initializing,
                                    true,
                                    memberInfo.InternalTcpEndPoint, memberInfo.InternalSecureTcpEndPoint,
                                    memberInfo.ExternalTcpEndPoint, memberInfo.ExternalSecureTcpEndPoint,
                                    memberInfo.HttpEndPoint,
                                    memberInfo.AdvertiseHostToClientAs, memberInfo.AdvertiseHttpPortToClientAs, memberInfo.AdvertiseTcpPortToClientAs,
                                    ownInfo.LastCommitPosition, ownInfo.WriterCheckpoint, ownInfo.ChaserCheckpoint,
                                    ownInfo.EpochPosition, ownInfo.EpochNumber, ownInfo.EpochId, ownInfo.NodePriority,
                                    memberInfo.IsReadOnlyReplica)
            };
        }
コード例 #6
0
        public StorageWriterService(IPublisher bus,
                                    ISubscriber subscribeToBus,
                                    TimeSpan minFlushDelay,
                                    TFChunkDb db,
                                    TFChunkWriter writer,
                                    IIndexWriter indexWriter,
                                    IEpochManager epochManager,
                                    QueueStatsManager queueStatsManager)
        {
            Ensure.NotNull(bus, "bus");
            Ensure.NotNull(subscribeToBus, "subscribeToBus");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(writer, "writer");
            Ensure.NotNull(indexWriter, "indexWriter");
            Ensure.NotNull(epochManager, "epochManager");

            Bus             = bus;
            _subscribeToBus = subscribeToBus;
            Db           = db;
            _indexWriter = indexWriter;
            EpochManager = epochManager;

            _minFlushDelay      = minFlushDelay.TotalMilliseconds * TicksPerMs;
            _lastFlushDelay     = 0;
            _lastFlushTimestamp = _watch.ElapsedTicks;

            Writer = writer;
            Writer.Open();

            _writerBus         = new InMemoryBus("StorageWriterBus", watchSlowMsg: false);
            StorageWriterQueue = QueuedHandler.CreateQueuedHandler(new AdHocHandler <Message>(CommonHandle),
                                                                   "StorageWriterQueue",
                                                                   queueStatsManager,
                                                                   true,
                                                                   TimeSpan.FromMilliseconds(500));
            _tasks.Add(StorageWriterQueue.Start());

            SubscribeToMessage <SystemMessage.SystemInit>();
            SubscribeToMessage <SystemMessage.StateChangeMessage>();
            SubscribeToMessage <SystemMessage.WriteEpoch>();
            SubscribeToMessage <SystemMessage.WaitForChaserToCatchUp>();
            SubscribeToMessage <StorageMessage.WritePrepares>();
            SubscribeToMessage <StorageMessage.WriteDelete>();
            SubscribeToMessage <StorageMessage.WriteTransactionStart>();
            SubscribeToMessage <StorageMessage.WriteTransactionData>();
            SubscribeToMessage <StorageMessage.WriteTransactionEnd>();
            SubscribeToMessage <StorageMessage.WriteCommit>();
        }
コード例 #7
0
        public StorageWriterService(IPublisher bus,
                                    ISubscriber subscribeToBus,
                                    int minFlushDelayMs,
                                    TFChunkDb db,
                                    TFChunkWriter writer,
                                    IReadIndex readIndex,
                                    IEpochManager epochManager)
        {
            Ensure.NotNull(bus, "bus");
            Ensure.NotNull(subscribeToBus, "subscribeToBus");
            Ensure.Nonnegative(minFlushDelayMs, "minFlushDelayMs");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(writer, "writer");
            Ensure.NotNull(readIndex, "readIndex");
            Ensure.NotNull(epochManager, "epochManager");

            Bus             = bus;
            _subscribeToBus = subscribeToBus;
            Db           = db;
            ReadIndex    = readIndex;
            EpochManager = epochManager;

            _minFlushDelay      = minFlushDelayMs * TicksPerMs;
            _lastFlushDelay     = 0;
            _lastFlushTimestamp = _watch.ElapsedTicks;

            Writer = writer;
            Writer.Open();

            _writerBus         = new InMemoryBus("StorageWriterBus", watchSlowMsg: false);
            StorageWriterQueue = new QueuedHandler(new AdHocHandler <Message>(CommonHandle),
                                                   "StorageWriterQueue",
                                                   true,
                                                   TimeSpan.FromMilliseconds(500));
            StorageWriterQueue.Start();

            SubscribeToMessage <SystemMessage.SystemInit>();
            SubscribeToMessage <SystemMessage.StateChangeMessage>();
            SubscribeToMessage <SystemMessage.WriteEpoch>();
            SubscribeToMessage <SystemMessage.WaitForChaserToCatchUp>();
            SubscribeToMessage <StorageMessage.WritePrepares>();
            SubscribeToMessage <StorageMessage.WriteDelete>();
            SubscribeToMessage <StorageMessage.WriteTransactionStart>();
            SubscribeToMessage <StorageMessage.WriteTransactionData>();
            SubscribeToMessage <StorageMessage.WriteTransactionPrepare>();
            SubscribeToMessage <StorageMessage.WriteCommit>();
        }
コード例 #8
0
        public ElectionsService(IPublisher publisher,
                                VNodeInfo nodeInfo,
                                int clusterSize,
                                ICheckpoint writerCheckpoint,
                                ICheckpoint chaserCheckpoint,
                                IEpochManager epochManager,
                                Func <long> getLastCommitPosition,
                                int nodePriority,
                                ITimeProvider timeProvider)
        {
            Ensure.NotNull(publisher, nameof(publisher));
            Ensure.NotNull(nodeInfo, nameof(nodeInfo));
            Ensure.Positive(clusterSize, nameof(clusterSize));
            Ensure.NotNull(writerCheckpoint, nameof(writerCheckpoint));
            Ensure.NotNull(chaserCheckpoint, nameof(chaserCheckpoint));
            Ensure.NotNull(epochManager, nameof(epochManager));
            Ensure.NotNull(getLastCommitPosition, nameof(getLastCommitPosition));
            Ensure.NotNull(timeProvider, nameof(timeProvider));

            _publisher             = publisher;
            _nodeInfo              = nodeInfo;
            _publisherEnvelope     = new PublishEnvelope(_publisher);
            _clusterSize           = clusterSize;
            _writerCheckpoint      = writerCheckpoint;
            _chaserCheckpoint      = chaserCheckpoint;
            _epochManager          = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority          = nodePriority;
            _timeProvider          = timeProvider;

            var ownInfo = GetOwnInfo();

            _servers = new[] {
                MemberInfo.ForVNode(nodeInfo.InstanceId,
                                    _timeProvider.UtcNow,
                                    VNodeState.Initializing,
                                    true,
                                    nodeInfo.InternalTcp, nodeInfo.InternalSecureTcp,
                                    nodeInfo.ExternalTcp, nodeInfo.ExternalSecureTcp,
                                    nodeInfo.InternalHttp, nodeInfo.ExternalHttp,
                                    ownInfo.LastCommitPosition, ownInfo.WriterCheckpoint, ownInfo.ChaserCheckpoint,
                                    ownInfo.EpochPosition, ownInfo.EpochNumber, ownInfo.EpochId, ownInfo.NodePriority,
                                    nodeInfo.IsReadOnlyReplica)
            };
        }
コード例 #9
0
        public ElectionsService(IPublisher publisher,
                                VNodeInfo nodeInfo,
                                int clusterSize,
                                ICheckpoint writerCheckpoint,
                                ICheckpoint chaserCheckpoint,
                                IEpochManager epochManager,
                                Func <long> getLastCommitPosition,
                                int nodePriority)
        {
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(nodeInfo, "nodeInfo");
            Ensure.Positive(clusterSize, "clusterSize");
            Ensure.NotNull(writerCheckpoint, "writerCheckpoint");
            Ensure.NotNull(chaserCheckpoint, "chaserCheckpoint");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(getLastCommitPosition, "getLastCommitPosition");

            _publisher             = publisher;
            _nodeInfo              = nodeInfo;
            _publisherEnvelope     = new PublishEnvelope(_publisher);
            _clusterSize           = clusterSize;
            _writerCheckpoint      = writerCheckpoint;
            _chaserCheckpoint      = chaserCheckpoint;
            _epochManager          = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority          = nodePriority;

            var ownInfo = GetOwnInfo();

            _servers = new[]
            {
                MemberInfo.ForVNode(nodeInfo.InstanceId,
                                    DateTime.UtcNow,
                                    VNodeState.Initializing,
                                    true,
                                    nodeInfo.InternalTcp, nodeInfo.InternalSecureTcp,
                                    nodeInfo.ExternalTcp, nodeInfo.ExternalSecureTcp,
                                    nodeInfo.InternalHttp, nodeInfo.ExternalHttp,
                                    ownInfo.LastCommitPosition, ownInfo.WriterCheckpoint, ownInfo.ChaserCheckpoint,
                                    ownInfo.EpochPosition, ownInfo.EpochNumber, ownInfo.EpochId, ownInfo.NodePriority)
            };
        }
コード例 #10
0
        public ClusterStorageWriterService(IPublisher bus,
                                           ISubscriber subscribeToBus,
                                           TimeSpan minFlushDelay,
                                           TFChunkDb db,
                                           TFChunkWriter writer,
                                           IIndexWriter indexWriter,
                                           IEpochManager epochManager,
                                           Func <long> getLastCommitPosition)
            : base(bus, subscribeToBus, minFlushDelay, db, writer, indexWriter, epochManager)
        {
            Ensure.NotNull(getLastCommitPosition, "getLastCommitPosition");

            _getLastCommitPosition = getLastCommitPosition;
            _framer = new LengthPrefixSuffixFramer(OnLogRecordUnframed, TFConsts.MaxLogRecordSize);

            SubscribeToMessage <ReplicationMessage.ReplicaSubscribed>();
            SubscribeToMessage <ReplicationMessage.CreateChunk>();
            SubscribeToMessage <ReplicationMessage.RawChunkBulk>();
            SubscribeToMessage <ReplicationMessage.DataChunkBulk>();
        }
コード例 #11
0
ファイル: StorageChaser.cs プロジェクト: tone81/EventStore
        public StorageChaser(IPublisher masterBus,
                             ICheckpoint writerCheckpoint,
                             ITransactionFileChaser chaser,
                             IReadIndex readIndex,
                             IEpochManager epochManager)
        {
            Ensure.NotNull(masterBus, "masterBus");
            Ensure.NotNull(chaser, "chaser");
            Ensure.NotNull(readIndex, "readIndex");
            Ensure.NotNull(epochManager, "epochManager");

            _masterBus        = masterBus;
            _writerCheckpoint = writerCheckpoint;
            _chaser           = chaser;
            _readIndex        = readIndex;
            _epochManager     = epochManager;

            _flushDelay = 0;
            _lastFlush  = _watch.ElapsedTicks;
        }
コード例 #12
0
        public ReplicaService(IPublisher publisher,
                              TFChunkDb db,
                              IEpochManager epochManager,
                              IPublisher networkSendQueue,
                              IAuthenticationProvider authProvider,
                              AuthorizationGateway authorizationGateway,
                              EndPoint internalTcp,
                              bool isReadOnlyReplica,
                              bool useSsl,
                              Func <X509Certificate, X509Chain, SslPolicyErrors, ValueTuple <bool, string> > sslServerCertValidator,
                              Func <X509Certificate> sslClientCertificateSelector,
                              TimeSpan heartbeatTimeout,
                              TimeSpan heartbeatInterval,
                              TimeSpan writeTimeout)
        {
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(networkSendQueue, "networkSendQueue");
            Ensure.NotNull(authProvider, "authProvider");
            Ensure.NotNull(authorizationGateway, "authorizationGateway");
            Ensure.NotNull(internalTcp, nameof(internalTcp));

            _publisher            = publisher;
            _db                   = db;
            _epochManager         = epochManager;
            _networkSendQueue     = networkSendQueue;
            _authProvider         = authProvider;
            _authorizationGateway = authorizationGateway;

            _internalTcp                  = internalTcp;
            _isReadOnlyReplica            = isReadOnlyReplica;
            _useSsl                       = useSsl;
            _sslServerCertValidator       = sslServerCertValidator;
            _sslClientCertificateSelector = sslClientCertificateSelector;
            _heartbeatTimeout             = heartbeatTimeout;
            _heartbeatInterval            = heartbeatInterval;

            _connector     = new TcpClientConnector();
            _tcpDispatcher = new InternalTcpDispatcher(writeTimeout);
        }
コード例 #13
0
        public StorageChaser(IPublisher masterBus,
                             ICheckpoint writerCheckpoint,
                             ITransactionFileChaser chaser,
                             IIndexCommitter indexCommitter,
                             IEpochManager epochManager)
        {
            Ensure.NotNull(masterBus, "masterBus");
            Ensure.NotNull(writerCheckpoint, "writerCheckpoint");
            Ensure.NotNull(chaser, "chaser");
            Ensure.NotNull(indexCommitter, "indexCommitter");
            Ensure.NotNull(epochManager, "epochManager");

            _masterBus        = masterBus;
            _writerCheckpoint = writerCheckpoint;
            _chaser           = chaser;
            _indexCommitter   = indexCommitter;
            _epochManager     = epochManager;

            _flushDelay = 0;
            _lastFlush  = _watch.ElapsedTicks;
        }
コード例 #14
0
        public NodeGossipService(IPublisher bus,
                                 IGossipSeedSource gossipSeedSource,
                                 VNodeInfo nodeInfo,
                                 ICheckpoint writerCheckpoint,
                                 ICheckpoint chaserCheckpoint,
                                 IEpochManager epochManager,
                                 Func <long> getLastCommitPosition,
                                 int nodePriority)
            : base(bus, gossipSeedSource, nodeInfo)
        {
            Ensure.NotNull(writerCheckpoint, "writerCheckpoint");
            Ensure.NotNull(chaserCheckpoint, "chaserCheckpoint");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(getLastCommitPosition, "getLastCommitPosition");

            _writerCheckpoint      = writerCheckpoint;
            _chaserCheckpoint      = chaserCheckpoint;
            _epochManager          = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority          = nodePriority;
        }
コード例 #15
0
        public NodeGossipService(IPublisher bus,
                                 IGossipSeedSource gossipSeedSource,
								 VNodeInfo nodeInfo,
                                 ICheckpoint writerCheckpoint,
                                 ICheckpoint chaserCheckpoint,
                                 IEpochManager epochManager,
                                 Func<long> getLastCommitPosition,
                                 int nodePriority)
                : base(bus, gossipSeedSource, nodeInfo)
        {
            Ensure.NotNull(writerCheckpoint, "writerCheckpoint");
            Ensure.NotNull(chaserCheckpoint, "chaserCheckpoint");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(getLastCommitPosition, "getLastCommitPosition");

            _writerCheckpoint = writerCheckpoint;
            _chaserCheckpoint = chaserCheckpoint;
            _epochManager = epochManager;
            _getLastCommitPosition = getLastCommitPosition;
            _nodePriority = nodePriority;
        }
コード例 #16
0
        public ReplicaService(IPublisher publisher,
                              TFChunkDb db,
                              IEpochManager epochManager,
                              IPublisher networkSendQueue,
                              IAuthenticationProvider authProvider,
                              AuthorizationGateway authorizationGateway,
                              VNodeInfo nodeInfo,
                              bool useSsl,
                              bool sslValidateServer,
                              X509CertificateCollection sslClientCertificates,
                              TimeSpan heartbeatTimeout,
                              TimeSpan heartbeatInterval,
                              TimeSpan writeTimeout)
        {
            Ensure.NotNull(publisher, "publisher");
            Ensure.NotNull(db, "db");
            Ensure.NotNull(epochManager, "epochManager");
            Ensure.NotNull(networkSendQueue, "networkSendQueue");
            Ensure.NotNull(authProvider, "authProvider");
            Ensure.NotNull(authorizationGateway, "authorizationGateway");
            Ensure.NotNull(nodeInfo, "nodeInfo");

            _publisher            = publisher;
            _db                   = db;
            _epochManager         = epochManager;
            _networkSendQueue     = networkSendQueue;
            _authProvider         = authProvider;
            _authorizationGateway = authorizationGateway;

            _nodeInfo              = nodeInfo;
            _useSsl                = useSsl;
            _sslValidateServer     = sslValidateServer;
            _sslClientCertificates = sslClientCertificates;
            _heartbeatTimeout      = heartbeatTimeout;
            _heartbeatInterval     = heartbeatInterval;

            _connector     = new TcpClientConnector();
            _tcpDispatcher = new InternalTcpDispatcher(writeTimeout);
        }
コード例 #17
0
ファイル: StorageChaser.cs プロジェクト: arthis/EventStore-1
        public StorageChaser(IPublisher leaderBus,
                             IReadOnlyCheckpoint writerCheckpoint,
                             ITransactionFileChaser chaser,
                             IIndexCommitterService indexCommitterService,
                             IEpochManager epochManager,
                             QueueStatsManager queueStatsManager)
        {
            Ensure.NotNull(leaderBus, "leaderBus");
            Ensure.NotNull(writerCheckpoint, "writerCheckpoint");
            Ensure.NotNull(chaser, "chaser");
            Ensure.NotNull(indexCommitterService, "indexCommitterService");
            Ensure.NotNull(epochManager, "epochManager");

            _leaderBus             = leaderBus;
            _writerCheckpoint      = writerCheckpoint;
            _chaser                = chaser;
            _indexCommitterService = indexCommitterService;
            _epochManager          = epochManager;
            _queueStats            = queueStatsManager.CreateQueueStatsCollector("Storage Chaser");

            _flushDelay = 0;
            _lastFlush  = _watch.ElapsedTicks;
        }
コード例 #18
0
        public ElectionsService(IPublisher publisher,
                                MemberInfo memberInfo,
                                int clusterSize,
                                IReadOnlyCheckpoint writerCheckpoint,
                                IReadOnlyCheckpoint chaserCheckpoint,
                                ICheckpoint proposalCheckpoint,
                                IEpochManager epochManager,
                                Func <long> getLastCommitPosition,
                                int nodePriority,
                                ITimeProvider timeProvider,
                                TimeSpan leaderElectionTimeout)
        {
            Ensure.NotNull(publisher, nameof(publisher));
            Ensure.NotNull(memberInfo, nameof(memberInfo));
            Ensure.Positive(clusterSize, nameof(clusterSize));
            Ensure.NotNull(writerCheckpoint, nameof(writerCheckpoint));
            Ensure.NotNull(chaserCheckpoint, nameof(chaserCheckpoint));
            Ensure.NotNull(proposalCheckpoint, nameof(proposalCheckpoint));
            Ensure.NotNull(epochManager, nameof(epochManager));
            Ensure.NotNull(getLastCommitPosition, nameof(getLastCommitPosition));
            Ensure.NotNull(timeProvider, nameof(timeProvider));
            if (leaderElectionTimeout.Seconds < 1)
            {
                throw new ArgumentOutOfRangeException(nameof(leaderElectionTimeout),
                                                      $"{nameof(leaderElectionTimeout)} should be greater than 1 second.");
            }
            if (memberInfo.IsReadOnlyReplica)
            {
                throw new ArgumentException("Read-only replicas are not allowed to run the Elections service.");
            }

            _publisher                     = publisher;
            _memberInfo                    = memberInfo;
            _publisherEnvelope             = new PublishEnvelope(_publisher);
            _clusterSize                   = clusterSize;
            _writerCheckpoint              = writerCheckpoint;
            _chaserCheckpoint              = chaserCheckpoint;
            _proposalCheckpoint            = proposalCheckpoint;
            _epochManager                  = epochManager;
            _getLastCommitPosition         = getLastCommitPosition;
            _nodePriority                  = nodePriority;
            _timeProvider                  = timeProvider;
            _leaderElectionProgressTimeout = leaderElectionTimeout;

            var lastEpoch = _epochManager.LastEpochNumber;

            if (_proposalCheckpoint.Read() < lastEpoch)
            {
                _proposalCheckpoint.Write(lastEpoch);
                _proposalCheckpoint.Flush();
            }

            var ownInfo = GetOwnInfo();

            _servers = new[] {
                MemberInfo.ForVNode(memberInfo.InstanceId,
                                    _timeProvider.UtcNow,
                                    VNodeState.Initializing,
                                    true,
                                    memberInfo.InternalTcpEndPoint, memberInfo.InternalSecureTcpEndPoint,
                                    memberInfo.ExternalTcpEndPoint, memberInfo.ExternalSecureTcpEndPoint,
                                    memberInfo.HttpEndPoint,
                                    memberInfo.AdvertiseHostToClientAs, memberInfo.AdvertiseHttpPortToClientAs, memberInfo.AdvertiseTcpPortToClientAs,
                                    ownInfo.LastCommitPosition, ownInfo.WriterCheckpoint, ownInfo.ChaserCheckpoint,
                                    ownInfo.EpochPosition, ownInfo.EpochNumber, ownInfo.EpochId, ownInfo.NodePriority,
                                    memberInfo.IsReadOnlyReplica)
            };
        }