public RoundBasedRegister(IIntercomMessageHub intercomMessageHub, IBallotGenerator ballotGenerator, ISynodConfiguration synodConfig, LeaseConfiguration leaseConfig, ILogger logger) { this.logger = logger; this.synodConfig = synodConfig; this.leaseConfig = leaseConfig; this.intercomMessageHub = intercomMessageHub; intercomMessageHub.Start(); readBallot = ballotGenerator.Null(); writeBallot = ballotGenerator.Null(); listener = intercomMessageHub.Subscribe(); listener.Where(m => Unsafe.Equals(m.Identity, LeaseReadMessage.MessageIdentity)) .Subscribe(OnReadReceived); listener.Where(m => Unsafe.Equals(m.Identity, LeaseWriteMessage.MessageIdentity)) .Subscribe(OnWriteReceived); ackReadStream = listener.Where(m => Unsafe.Equals(m.Identity, LeaseAckReadMessage.MessageIdentity)); nackReadStream = listener.Where(m => Unsafe.Equals(m.Identity, LeaseNackReadMessage.MessageIdentity)); ackWriteStream = listener.Where(m => Unsafe.Equals(m.Identity, LeaseAckWriteMessage.MessageIdentity)); nackWriteStream = listener.Where(m => Unsafe.Equals(m.Identity, LeaseNackWriteMessage.MessageIdentity)); }
public void TestTwoBallotsGeneratedWithinSafetyPeriod_HaveDifferentMessageNumber() { var identity = new byte[] {0}; var leaseConfig = new LeaseConfiguration { ClockDrift = TimeSpan.FromMilliseconds(500) }; var ballotGenerator = new BallotGenerator(leaseConfig); var ballot1 = ballotGenerator.New(identity); Thread.Sleep((int)leaseConfig.ClockDrift.TotalMilliseconds / 10); var ballot2 = ballotGenerator.New(identity); Assert.GreaterOrEqual(leaseConfig.ClockDrift, ballot2.Timestamp - ballot1.Timestamp); Assert.AreNotEqual(ballot1.MessageNumber, ballot2.MessageNumber); }
internal static RoundBasedRegisterTestSetup CreateRoundBasedRegister(IEnumerable<string> synod, string localNodeUri) { var intercomMessageHubSocketFactory = new IntercomMessageHubSocketFactory(); var socketFactory = new Mock<ISocketFactory>(); socketFactory.Setup(m => m.CreateSubscriberSocket()).Returns(intercomMessageHubSocketFactory.CreateSubscriberSocket); var appConfig = new ApplicationConfiguration { Synod = new SynodConfiguration { Members = synod, ClockDrift = TimeSpan.FromMilliseconds(100), MessageRoundtrip = TimeSpan.FromSeconds(4), NodeResponseTimeout = TimeSpan.FromSeconds(2), LocalNode = localNodeUri, MaxLeaseTimeSpan = TimeSpan.FromSeconds(10) } }; var leaseConfig = new LeaseConfiguration { ClockDrift = appConfig.Synod.ClockDrift, MaxLeaseTimeSpan = appConfig.Synod.MaxLeaseTimeSpan, MessageRoundtrip = appConfig.Synod.MessageRoundtrip, NodeResponseTimeout = appConfig.Synod.NodeResponseTimeout }; var socketConfig = new SocketConfiguration { ReceivingHighWatermark = 1000, SendingHighWatermark = 1000, Linger = TimeSpan.Zero }; var synodConfig = new Rendezvous.Consensus.SynodConfiguration(new SynodConfigurationProvider(appConfig)); var loggerMock = new Mock<ILogger>(); var intercomMessageHub = new IntercomMessageHub(new SocketFactory(socketConfig), synodConfig, loggerMock.Object); var ballotGenerator = new BallotGenerator(leaseConfig); var roundBasedRegister = new RoundBasedRegister(intercomMessageHub, ballotGenerator, synodConfig, leaseConfig, loggerMock.Object); Thread.Sleep(TimeSpan.FromMilliseconds(400)); return new RoundBasedRegisterTestSetup(ballotGenerator, synodConfig.LocalNode, roundBasedRegister); }
private void ValidateConfiguration(LeaseConfiguration config) { if (config.NodeResponseTimeout.TotalMilliseconds * 2 > config.MessageRoundtrip.TotalMilliseconds) { throw new Exception("NodeResponseTimeout[{config.NodeResponseTimeout.TotalMilliseconds} msec] " + "should be at least 2 times shorter than " + "MessageRoundtrip[{config.MessageRoundtrip.TotalMilliseconds} msec]"); } if (config.MaxLeaseTimeSpan - TimeSpan.FromTicks(config.MessageRoundtrip.Ticks * 2) - config.ClockDrift <= TimeSpan.Zero) { throw new Exception($"MaxLeaseTimeSpan[{config.MaxLeaseTimeSpan.TotalMilliseconds} msec] " + "should be longer than " + $"(2 * MessageRoundtrip[{config.MessageRoundtrip.TotalMilliseconds} msec] " + $"+ ClockDrift[{config.ClockDrift.TotalMilliseconds} msec])"); } }
public LeaseProvider(IRoundBasedRegister register, IBallotGenerator ballotGenerator, LeaseConfiguration config, ISynodConfiguration synodConfig, RendezvousConfiguration rendezvousConfig, ILogger logger) { ValidateConfiguration(config); WaitBeforeNextLeaseIssued(config); localNode = synodConfig.LocalNode; this.logger = logger; this.config = config; this.rendezvousConfig = rendezvousConfig; this.ballotGenerator = ballotGenerator; this.register = register; leaseRenewWaitTimeout = TimeSpan.FromMilliseconds(10); renewGateway = new SemaphoreSlim(1); leaseTimer = new Timer(state => ScheduledReadOrRenewLease(), null, TimeSpan.FromMilliseconds(-1), TimeSpan.FromMilliseconds(-1)); }
private void WaitBeforeNextLeaseIssued(LeaseConfiguration config) { Sleep(config.MaxLeaseTimeSpan); }
public BallotGenerator(LeaseConfiguration config) { this.config = config; lastBallotTimestamp = new BallotTimestamp {MessageNumber = 0, Timestamp = DateTime.UtcNow}; NullBallot = new Ballot(DateTime.MinValue, 0, Empty); }