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);
        }
Exemple #2
0
        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()));
        }
Exemple #5
0
        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);
                }
            }
        }