public LinkerService(ILinkerConnectionBuilder originBuilder, ILinkerConnectionBuilder destinationBuilder, IPositionRepository positionRepository, IFilterService filterService, Settings settings, ILinkerLogger logger) { Ensure.NotNull(originBuilder, nameof(originBuilder)); Ensure.NotNull(destinationBuilder, nameof(destinationBuilder)); Ensure.NotNull(positionRepository, nameof(positionRepository)); _logger = logger; Name = $"Replica From-{originBuilder.ConnectionName}-To-{destinationBuilder.ConnectionName}"; _connectionBuilderForOrigin = originBuilder; _connectionBuilderForDestination = destinationBuilder; _positionRepository = positionRepository; _filterService = filterService; _handleConflicts = settings.HandleConflicts; _resolveLinkTos = settings.ResolveLinkTos; _timerForStats = new Timer(settings.StatsInterval); _timerForStats.Elapsed += _timerForStats_Elapsed; _processor = new Timer(settings.SynchronisationInterval); _processor.Elapsed += Processor_Elapsed; _perfTunedSettings = new PerfTuneSettings(settings.MaxBufferSize, settings.MaxLiveQueue, settings.ReadBatchSize); _replicaHelper = new LinkerHelper(); }
public PerfTuneSettings OptimizeSettings(long lastExecutionTime, PerfTuneSettings currentPerfTuneSettings, int maxBufferSizeLimit = 1500, double differentialLimit = 1.10, int geoReplicaClock = 1000) { if (differentialLimit > 1.50) { differentialLimit = 1.50; } if (differentialLimit < 1) { differentialLimit = 1.01; } if (maxBufferSizeLimit > 5000) { maxBufferSizeLimit = 5000; } if (maxBufferSizeLimit < 1) { maxBufferSizeLimit = 1; } var optimizedMaxBufferSize = currentPerfTuneSettings.MaxBufferSize; var optimizedMaxLiveQueue = currentPerfTuneSettings.MaxLiveQueue; var optimizedReadBatchSize = currentPerfTuneSettings.ReadBatchSize; // Should we increase performances? if (currentPerfTuneSettings.MaxBufferSize <= maxBufferSizeLimit && lastExecutionTime < geoReplicaClock) { optimizedMaxBufferSize = Convert.ToInt32(Math.Round(currentPerfTuneSettings.MaxBufferSize * differentialLimit, MidpointRounding.AwayFromZero)); } if (currentPerfTuneSettings.MaxLiveQueue <= CatchUpSubscriptionSettings.Default.MaxLiveQueueSize && lastExecutionTime < geoReplicaClock) { optimizedMaxLiveQueue = Convert.ToInt32(Math.Round(currentPerfTuneSettings.MaxLiveQueue * differentialLimit, MidpointRounding.AwayFromZero)); } if (currentPerfTuneSettings.ReadBatchSize <= CatchUpSubscriptionSettings.Default.ReadBatchSize && lastExecutionTime < geoReplicaClock) { optimizedReadBatchSize = Convert.ToInt32(Math.Round(currentPerfTuneSettings.ReadBatchSize * differentialLimit, MidpointRounding.AwayFromZero)); } // Should we decrease performances? if (currentPerfTuneSettings.MaxBufferSize >= maxBufferSizeLimit && lastExecutionTime > geoReplicaClock) { optimizedMaxBufferSize = Convert.ToInt32(Math.Round(currentPerfTuneSettings.MaxBufferSize / differentialLimit, MidpointRounding.AwayFromZero)); } if (currentPerfTuneSettings.MaxLiveQueue >= CatchUpSubscriptionSettings.Default.MaxLiveQueueSize && lastExecutionTime > geoReplicaClock) { optimizedMaxLiveQueue = Convert.ToInt32(Math.Round(currentPerfTuneSettings.MaxLiveQueue / differentialLimit, MidpointRounding.AwayFromZero)); } if (currentPerfTuneSettings.ReadBatchSize >= CatchUpSubscriptionSettings.Default.ReadBatchSize && lastExecutionTime > geoReplicaClock) { optimizedReadBatchSize = Convert.ToInt32(Math.Round(currentPerfTuneSettings.ReadBatchSize / differentialLimit, MidpointRounding.AwayFromZero)); } return(new PerfTuneSettings(optimizedMaxBufferSize, optimizedMaxLiveQueue, optimizedReadBatchSize)); }
private void Processor_Elapsed(object sender, ElapsedEventArgs e) { if (_internalBuffer.IsEmpty) { return; } try { _processor.Stop(); _allCatchUpSubscription.Stop(); var watch = System.Diagnostics.Stopwatch.StartNew(); var eventsToProcess = _internalBuffer.Count; var oldPerfSettings = _perfTunedSettings.Clone() as PerfTuneSettings; ProcessQueueAndWaitAll(); watch.Stop(); var elapsedMs = watch.ElapsedMilliseconds; _logger.Debug($"{Name} Replicated '{eventsToProcess}' events in {elapsedMs}ms"); _perfTunedSettings = _replicaHelper.OptimizeSettings(elapsedMs, _perfTunedSettings); if (!_perfTunedSettings.Equals(oldPerfSettings)) { _logger.Debug($"{Name} Old PerfSettings: {oldPerfSettings}"); _logger.Debug($"{Name} New PerfSettings: {_perfTunedSettings}"); } Subscribe(_lastPosition); _processor.Start(); } catch (Exception exception) { _logger.Error($"Error while Processor_Elapsed: {exception.GetBaseException().Message}"); Stop(); Start(); } }
protected bool Equals(PerfTuneSettings other) { return(MaxBufferSize == other.MaxBufferSize && MaxLiveQueue == other.MaxLiveQueue && ReadBatchSize == other.ReadBatchSize); }