private void startSyncIfNeeded() { if (IsRunningSync) { return; } if (syncTimeStopwatch == null) { syncTimeStopwatch = stopwatchProvider.Create(MeasuredOperation.Sync); syncTimeStopwatch.Start(); } var state = isFrozen ? Sleep : queue.Dequeue(); analyticsService.SyncOperationStarted.Track(state.ToString()); IsRunningSync = state != Sleep; if (IsRunningSync && progress.FirstAsync().Wait() != SyncProgress.Syncing) { progress.OnNext(SyncProgress.Syncing); } orchestrator.Start(state); }
public static IStopwatch MaybeCreateStopwatch(this IStopwatchProvider stopwatchProvider, MeasuredOperation operation, float probability) { var samplingFactor = samplingRandom.NextDouble(); if (samplingFactor <= probability) { return stopwatchProvider.Create(operation); } return null; }
public IObservable <SyncOutcome> Execute() { var syncTimeStopwatch = stopwatchProvider.Create(MeasuredOperation.BackgroundSync); syncTimeStopwatch.Start(); analyticsService.BackgroundSyncStarted.Track(); return(syncManager.ForceFullSync() .LastAsync() .Select(_ => SyncOutcome.NewData) .Catch((Exception error) => syncFailed(error)) .Do(outcome => { syncTimeStopwatch.Stop(); analyticsService.BackgroundSyncFinished.Track(outcome.ToString()); })); }
public IObservable <IEnumerable <IThreadSafeTimeEntry> > Execute() { var updateTimeMeasurement = stopwatchProvider.Create(MeasuredOperation.UpdateTimeEntriesGroup); updateTimeMeasurement.Start(); var dtosMap = timeEntriesDtos.ToDictionary(dto => dto.Id); var ids = dtosMap.Keys.ToArray(); return(interactorFactory.GetMultipleTimeEntriesById(ids) .Execute() .Select(timeEntries => timeEntries.Select(timeEntry => createUpdatedTimeEntry(timeEntry, dtosMap[timeEntry.Id]))) .SelectMany(dataSource.TimeEntries.BatchUpdate) .UnwrapUpdatedThreadSafeEntities() .Do(syncManager.InitiatePushSync) .Do(_ => updateTimeMeasurement.Stop())); }
private async Task RunBackgroundTaskAsync(CancellationToken cancellationToken) { var sleepMinimalInterval = TimeSpan.FromMilliseconds(options.MinimalSleepIntervalMilliseconds); var roundInterval = TimeSpan.FromMilliseconds(options.RoundIntervalMilliseconds); var random = new Random(); var stopwatch = stopwatchProvider.Create(); while (!cancellationToken.IsCancellationRequested) { stopwatch.Restart(); /* Background jobs * * 0. Update member list & related counter threshold * 1. Calculate the counters in previous round * 2. Send push requests * 3. Send pull requests (switch to C states & clear lower, higher counter) */ try { IReadOnlyList <Rumor> rumorsToBeSent = new Rumor[0]; var memberList = memberListProvider.Invoke(); await semaphore.ProtectAsync(() => { UpdateCounterThresholds(memberList); logger.LogDebug("Counter thresholds updated"); UpdateRumorCountersFromPreviousRound(); logger.LogDebug("Rumor counters updated"); rumorsToBeSent = pushStateRumorCounterDictionary .Select(p => new Rumor { Counter = p.Value, Payload = p.Key }) .ToArray(); }, cancellationToken); // 2. Send push requests logger.LogDebug("Pushing {0} rumors", rumorsToBeSent.Count); var activePushTask = ActivePushRumors(random, memberList, rumorsToBeSent, cancellationToken); // 3. Send pull requests (switch to C states & clear lower, higher counter) var pulledRumors = (await ActivePullRumors(random, memberList, cancellationToken)).ToArray(); logger.LogDebug("Pulled {0} rumors", pulledRumors.Count()); var activePullTask = semaphore.ProtectAsync(() => { foreach (var rumor in pulledRumors) { ReceivePulledRumor(rumor); } }, cancellationToken); await Task.WhenAll(activePushTask, activePullTask); } catch (Exception ex) { logger.LogError(ex, ex.Message); } stopwatch.Stop(); logger.LogDebug("Background loop finished in {0}ms", stopwatch.Elapsed.TotalMilliseconds); var sleepInterval = roundInterval - stopwatch.Elapsed; if (sleepInterval > sleepMinimalInterval) { logger.LogDebug("Background loop sleep {0}ms", sleepInterval.TotalMilliseconds); await Task.Delay(sleepInterval); } else { logger.LogWarning("The execution time too long: {0}", stopwatch.Elapsed); } } }