public void NullChecking()
        {
            Assert.Throws<ArgumentNullException>(() => new RetrySettings(null, s_sampleBackoff, Expiration.None).ToString());
            Assert.Throws<ArgumentNullException>(() => new RetrySettings(s_sampleBackoff, null, Expiration.None).ToString());
            Assert.Throws<ArgumentNullException>(() => new RetrySettings(s_sampleBackoff, s_sampleBackoff, null).ToString());

            // No exceptions here...
            var settings = new RetrySettings(s_sampleBackoff, s_sampleBackoff, Expiration.None, null);
            settings = new RetrySettings(s_sampleBackoff, s_sampleBackoff, Expiration.None, null, null);
        }
Exemple #2
0
        public Task InitialBackoffOverrideRespected()
        {
            var settings = RetrySettings.FromConstantBackoff(
                maxAttempts: 4, backoff: FiveSeconds, retryFilter: ex => true, backoffJitter: RetrySettings.NoJitter);
            var scheduler = new FakeScheduler();

            var sequence = RetryAttempt.CreateRetrySequence(settings, scheduler, initialBackoffOverride: OneSecond);

            // Should attempt at T=0, T=1, T=6, T=11.
            return(AssertAttemptsAsync(sequence, scheduler, () => new Exception(), 0, 1, 6, 11));
        }
Exemple #3
0
        public Task MaxAttemptsRespected()
        {
            var settings = RetrySettings.FromConstantBackoff(
                maxAttempts: 4, backoff: OneSecond, retryFilter: ex => true, backoffJitter: RetrySettings.NoJitter);
            var scheduler = new FakeScheduler();

            var sequence = RetryAttempt.CreateRetrySequence(settings, scheduler);

            // Should attempt at T=0, T=1, T=2, T=3, then stop because we're only allowed four attempts.
            return(AssertAttemptsAsync(sequence, scheduler, () => new Exception(), 0, 1, 2, 3));
        }
        public void FromConstantBackoff_DefaultJitter()
        {
            var backoff  = TimeSpan.FromSeconds(3);
            var filter   = RetrySettings.FilterForStatusCodes(StatusCode.Aborted);
            var settings = RetrySettings.FromConstantBackoff(10, backoff, filter);

            Assert.Equal(10, settings.MaxAttempts);
            Assert.Equal(backoff, settings.InitialBackoff);
            Assert.Equal(backoff, settings.MaxBackoff);
            Assert.Same(filter, settings.RetryFilter);
            Assert.Same(RetrySettings.RandomJitter, settings.BackoffJitter);
        }
        public RowAsyncEnumerator(
            BigtableClientImpl client,
            ReadRowsRequest originalRequest,
            CallSettings callSettings,
            RetrySettings retrySettings)
        {
            _client        = client;
            _callSettings  = callSettings;
            _retrySettings = retrySettings;

            _requestManager = new BigtableReadRowsRequestManager(originalRequest);
        }
Exemple #6
0
        private async Task DoBodyProccessAsync(BodySetting bodySetting, RetrySettings retrySettings_4FailedItems)
        {
            if (bodySetting == null)
            {
                return;
            }
            var bodyResult1 = await DoBodyAsync(bodySetting);

            var bodyResult2 = bodyResult1;

            await SaveBodyAsync(bodySetting, bodyResult2, retrySettings_4FailedItems);
        }
Exemple #7
0
 internal ReadRowsStream(
     BigtableClientImpl client,
     ReadRowsRequest originalRequest,
     CallSettings callSettings,
     RetrySettings retrySettings,
     BigtableServiceApiClient.ReadRowsStream underlyingStream)
 {
     _client           = client;
     _originalRequest  = originalRequest;
     _callSettings     = callSettings;
     _retrySettings    = retrySettings;
     _underlyingStream = underlyingStream;
 }
        private static AsyncRetryPolicy GetPolicy(
            RetrySettings settings,
            ILogger logger)
        {
            var policyBuilder = Policy
                                .Handle <ApiException>(ex => settings.RetryTypes.Any(t => ex.GetType() == t));

            return(policyBuilder
                   .WaitAndRetryAsync(
                       settings.MaxRetryCount,
                       retryAttempt => TimeSpan.FromSeconds(Math.Pow(retryAttempt, settings.Exponent) * settings.Multiplier),
                       (exception, timespan, context) => OnRetryCallback(exception, timespan, context, logger)));
        }
Exemple #9
0
        public Task PredicateRespected()
        {
            int count = 0;
            Func <Exception> exceptionProvider = () => ++ count == 3 ? new Exception() : new RpcException(Status.DefaultCancelled);

            var settings = RetrySettings.FromExponentialBackoff(
                maxAttempts: 4, initialBackoff: OneSecond, maxBackoff: FiveSeconds,
                backoffMultiplier: 1, retryFilter: ex => ex is RpcException, backoffJitter: RetrySettings.NoJitter);
            var scheduler = new FakeScheduler();
            var sequence  = RetryAttempt.CreateRetrySequence(settings, scheduler);

            return(AssertAttemptsAsync(sequence, scheduler, exceptionProvider, 0, 1, 2));
        }
Exemple #10
0
        public Task DeadlineRespected()
        {
            var settings = RetrySettings.FromExponentialBackoff(
                maxAttempts: 10, initialBackoff: OneSecond, maxBackoff: FiveSeconds,
                backoffMultiplier: 2, retryFilter: ex => true, backoffJitter: RetrySettings.NoJitter);
            var scheduler = new FakeScheduler();
            var deadline  = scheduler.Clock.GetCurrentDateTimeUtc() + FiveSeconds;

            var sequence = RetryAttempt.CreateRetrySequence(settings, scheduler, deadline, scheduler.Clock);

            // Should attempt at T=0, T=1, T=3, then stop because the next attempt would be after the deadline.
            return(AssertAttemptsAsync(sequence, scheduler, () => new Exception(), 0, 1, 3));
        }
Exemple #11
0
 public void RetrySettingsTiming()
 {
     // Sample: RetrySettingsTiming
     // Each delay is double the previous one, with a maximum of 5s.
     // The first delay is 1s, then 2s, then 4s, then 5s, then 5s, etc.
     // Only aborted RPCs are retried in this example.
     RetrySettings settings = RetrySettings.FromExponentialBackoff(
         maxAttempts: 10,
         initialBackoff: TimeSpan.FromSeconds(1),
         maxBackoff: TimeSpan.FromSeconds(5),
         backoffMultiplier: 2.0,
         retryFilter: RetrySettings.FilterForStatusCodes(StatusCode.Aborted));
     // End sample
 }
        private IRestClient GetRestClientWithRetries()
        {
            // configure to retry 3 times with 100ms between attempts, and no backoff.
            var retrySettings = new RetrySettings(
                RetryCount,
                RetryExponent,
                RetryMultiplier,
                new[] { typeof(ServiceUnavailableException) });

            return(new ResilientRestClient(
                       retrySettings,
                       this.mockRestClient.Object,
                       MockLogger.Object));
        }
Exemple #13
0
        public Task JitterRespected()
        {
            var settings = RetrySettings.FromExponentialBackoff(
                maxAttempts: 6, initialBackoff: TimeSpan.FromSeconds(2), maxBackoff: TimeSpan.FromSeconds(10),
                backoffMultiplier: 2, retryFilter: ex => true, backoffJitter: new HalvingJitter());
            var scheduler = new FakeScheduler();


            var sequence = RetryAttempt.CreateRetrySequence(settings, scheduler);

            // Sequence of theoretical backoffs is 2, 4, 8, 10, 10, 10
            // Sequence of jittered backoffs is 1, 2, 4, 5, 5.
            return(AssertAttemptsAsync(sequence, scheduler, () => new Exception(), 0, 1, 3, 7, 12, 17));
        }
        public void FromExponentialBackoff_SpecificJitter()
        {
            var initialBackoff = TimeSpan.FromSeconds(3);
            var maxBackoff     = TimeSpan.FromSeconds(5);
            var filter         = RetrySettings.FilterForStatusCodes(StatusCode.Aborted);
            var settings       = RetrySettings.FromExponentialBackoff(10, initialBackoff, maxBackoff, 1.5, filter, RetrySettings.NoJitter);

            Assert.Equal(10, settings.MaxAttempts);
            Assert.Equal(initialBackoff, settings.InitialBackoff);
            Assert.Equal(maxBackoff, settings.MaxBackoff);
            Assert.Equal(1.5, settings.BackoffMultiplier);
            Assert.Same(filter, settings.RetryFilter);
            Assert.Same(RetrySettings.NoJitter, settings.BackoffJitter);
        }
        public RowAsyncEnumerator(
            BigtableClientImpl client,
            ReadRowsRequest originalRequest,
            CallSettings callSettings,
            RetrySettings retrySettings,
            BigtableServiceApiClient.ReadRowsStream stream)
        {
            _client        = client;
            _callSettings  = callSettings;
            _retrySettings = retrySettings;
            _stream        = stream;

            _requestManager = new BigtableReadRowsRequestManager(originalRequest);
        }
Exemple #16
0
        /// <summary>
        /// Вычислить задержку для указанного номера повторения.
        /// </summary>
        /// <param name="retrySettings">Настройки повторной обработки сообщений.</param>
        /// <param name="retryNumber">Номер повторной обработки.</param>
        /// <returns>Временной интервал.</returns>
        public TimeSpan Compute(RetrySettings retrySettings, int retryNumber)
        {
            // для больших значений retryNumber, Math.Pow быстро возвращает значение бесконечности,
            // поэтому дополнительных проверок делать не нужно.
            var newDelayTimeInSeconds = Math.Pow(2, retryNumber);

            // Если Delay превысил максимальное время выполнения, ограничиваем максимальным значением.
            if (newDelayTimeInSeconds > retrySettings.RetryMaxDelayInSeconds)
            {
                newDelayTimeInSeconds = retrySettings.RetryMaxDelayInSeconds;
            }

            return(TimeSpan.FromSeconds(newDelayTimeInSeconds));
        }
Exemple #17
0
        // TODO: This is a modified/simplified version of ApiCallRetryExtensions.WithRetry from Google.Api.Gax.Grpc. Can we combine them somehow?
        internal static async Task RetryOperationUntilCompleted(
            Func <Task <bool> > fn,
            IClock clock,
            IScheduler scheduler,
            CallSettings callSettings,
            RetrySettings retrySettings)
        {
            DateTime?overallDeadline = retrySettings.TotalExpiration.CalculateDeadline(clock);
            TimeSpan retryDelay      = retrySettings.RetryBackoff.Delay;
            TimeSpan callTimeout     = retrySettings.TimeoutBackoff.Delay;

            while (true)
            {
                DateTime attemptDeadline = clock.GetCurrentDateTimeUtc() + callTimeout;
                // Note: this handles a null total deadline due to "<" returning false if overallDeadline is null.
                DateTime     combinedDeadline    = overallDeadline < attemptDeadline ? overallDeadline.Value : attemptDeadline;
                CallSettings attemptCallSettings = callSettings.WithCallTiming(CallTiming.FromDeadline(combinedDeadline));
                TimeSpan     actualDelay         = retrySettings.DelayJitter.GetDelay(retryDelay);
                DateTime     expectedRetryTime;
                try
                {
                    bool isResponseOk = await fn().ConfigureAwait(false);

                    if (isResponseOk)
                    {
                        return;
                    }

                    expectedRetryTime = clock.GetCurrentDateTimeUtc() + actualDelay;
                    if (expectedRetryTime > overallDeadline)
                    {
                        // TODO: Can we get this string from somewhere?
                        throw new RpcException(new Status(StatusCode.DeadlineExceeded, "Deadline Exceeded"));
                    }
                }
                catch (RpcException e) when(retrySettings.RetryFilter(e))
                {
                    expectedRetryTime = clock.GetCurrentDateTimeUtc() + actualDelay;
                    if (expectedRetryTime > overallDeadline)
                    {
                        throw;
                    }
                }
                await scheduler.Delay(actualDelay, callSettings.CancellationToken.GetValueOrDefault()).ConfigureAwait(false);

                retryDelay  = retrySettings.RetryBackoff.NextDelay(retryDelay);
                callTimeout = retrySettings.TimeoutBackoff.NextDelay(callTimeout);
            }
        }
        public void NextBackoff(double current, double expectedNext)
        {
            var settings = new RetrySettings(
                maxAttempts: 5,
                initialBackoff: TimeSpan.FromSeconds(1.0),
                maxBackoff: TimeSpan.FromSeconds(5.0),
                backoffMultiplier: 2.0,
                e => true,
                RetrySettings.NoJitter);

            var expected = TimeSpan.FromSeconds(expectedNext);
            var actual   = settings.NextBackoff(TimeSpan.FromSeconds(current));

            Assert.Equal(expected, actual);
        }
Exemple #19
0
        public void WithExpiration_SettingsWithRetry()
        {
            var          token           = new CancellationTokenSource().Token;
            var          backoffSettings = new BackoffSettings(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(10), 1.5);
            var          retry           = new RetrySettings(backoffSettings, backoffSettings, Expiration.FromTimeout(TimeSpan.FromSeconds(5)));
            var          originalTiming  = CallTiming.FromRetry(retry);
            CallSettings settings        = CallSettings.FromCancellationToken(token).WithCallTiming(originalTiming);
            Expiration   expiration      = Expiration.FromTimeout(TimeSpan.FromSeconds(1));
            var          result          = settings.WithExpiration(expiration);

            Assert.Same(expiration, result.Timing.Retry.TotalExpiration);
            Assert.Same(backoffSettings, result.Timing.Retry.RetryBackoff);
            Assert.Same(backoffSettings, result.Timing.Retry.TimeoutBackoff);
            Assert.Equal(token, result.CancellationToken);
        }
Exemple #20
0
        public void WithNewExpiration()
        {
            var retryBackoff   = new BackoffSettings(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3));
            var timeoutBackoff = new BackoffSettings(TimeSpan.FromSeconds(2), TimeSpan.FromSeconds(3));
            var original       = new RetrySettings(retryBackoff, timeoutBackoff, Expiration.FromTimeout(TimeSpan.FromSeconds(5)),
                                                   e => false, RetrySettings.NoJitter);
            var newExpiration = Expiration.FromDeadline(DateTime.UtcNow);
            var newSettings   = original.WithTotalExpiration(newExpiration);

            Assert.Same(original.RetryBackoff, newSettings.RetryBackoff);
            Assert.Same(original.TimeoutBackoff, newSettings.TimeoutBackoff);
            Assert.Same(original.RetryFilter, newSettings.RetryFilter);
            Assert.Same(original.DelayJitter, newSettings.DelayJitter);
            Assert.Same(newExpiration, newSettings.TotalExpiration);
        }
Exemple #21
0
 /// <summary>
 /// Constructor with complete control that does not perform any validation.
 /// </summary>
 internal ResultStream(
     SpannerClient client,
     ReadOrQueryRequest request,
     Session session,
     CallSettings callSettings,
     int maxBufferSize,
     RetrySettings retrySettings)
 {
     _buffer        = new LinkedList <PartialResultSet>();
     _client        = GaxPreconditions.CheckNotNull(client, nameof(client));
     _request       = GaxPreconditions.CheckNotNull(request, nameof(request));
     _session       = GaxPreconditions.CheckNotNull(session, nameof(session));
     _callSettings  = callSettings;
     _maxBufferSize = GaxPreconditions.CheckArgumentRange(maxBufferSize, nameof(maxBufferSize), 1, 10_000);
     _retrySettings = GaxPreconditions.CheckNotNull(retrySettings, nameof(retrySettings));
 }
Exemple #22
0
        /// <summary>
        /// Установить информацию о повторной обработке в текущий скоуп логгера.
        /// </summary>
        /// <param name="properties">Метаданные сообщения.</param>
        /// <param name="subscriberSettings">Настройки повтора подписчика.</param>
        /// <param name="loggingScope">Скоуп.</param>
        /// <returns>Номер повторной попытки, признак попытки последней обработки.</returns>
        internal static (int retryNumber, bool isLastRetry) EnsureRetryInfo(
            this IBasicProperties properties,
            RetrySettings subscriberSettings,
            Dictionary <string, object?> loggingScope
            )
        {
            var isLastRetry = properties.IsLastRetry(subscriberSettings, out var retryCount);

            loggingScope["RetryNumber"] = retryCount;

            if (isLastRetry)
            {
                loggingScope["IsLastRetry"] = true;
            }

            return(retryCount, isLastRetry);
        }
Exemple #23
0
        public override void SetUp()
        {
            _latched   = false;
            _unlatched = false;
            _pingFails = false;

            theSettings = new RetrySettings();

            theRetryAgent = new LightweightRetryAgent(this, theSettings);

            for (int i = 0; i < batches.Length; i++)
            {
                batches[i] = batchForEnvelopes(15);
            }

            _enqueued.Clear();
        }
Exemple #24
0
 public LogUploader(
     LoggingServiceV2Client client,
     IScheduler scheduler,
     IClock clock,
     ILogQueue logQ,
     LogEntry logsLostWarningTemplate,
     int maxUploadBatchSize,
     RetrySettings serverErrorRetrySettings)
 {
     _client    = client;
     _scheduler = scheduler;
     _clock     = clock;
     _logQ      = logQ;
     _logsLostWarningTemplate  = logsLostWarningTemplate;
     _maxUploadBatchSize       = maxUploadBatchSize;
     _serverErrorRetrySettings = serverErrorRetrySettings;
     _uploaderTaskCancellation = new CancellationTokenSource();
     _uploaderTask             = Task.Run(() => RunUploader(_uploaderTaskCancellation.Token));
 }
Exemple #25
0
        internal WatchStream(IScheduler scheduler, IWatchState state, Target target, FirestoreDb db, CancellationToken cancellationToken)
        {
            _scheduler = scheduler;
            _state     = state;
            _target    = target;
            _db        = db;
            _callbackCancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
            _networkCancellationTokenSource  = CancellationTokenSource.CreateLinkedTokenSource(_callbackCancellationTokenSource.Token);
            _listenCallSettings = CallSettings.FromHeader(FirestoreClientImpl.ResourcePrefixHeader, db.RootPath);

            // TODO: Make these configurable?
            _backoffSettings = RetrySettings.FromExponentialBackoff(
                maxAttempts: int.MaxValue,
                initialBackoff: TimeSpan.FromSeconds(1),
                maxBackoff: TimeSpan.FromSeconds(30),
                backoffMultiplier: 2.0,
                retryFilter: _ => false, // Ignored
                backoffJitter: RetrySettings.RandomJitter);
        }
Exemple #26
0
        /// <summary>
        /// Получить, является ли текущая попытка обработки последней.
        /// </summary>
        /// <param name="properties">Метаданные сообщения.</param>
        /// <param name="retrySettings">Настройки повтора подписчика.</param>
        /// <param name="retryCount">Количество повторных попыток.</param>
        /// <returns>Признак попытки последней обработки.</returns>
        internal static bool IsLastRetry(
            this IBasicProperties properties,
            RetrySettings retrySettings,
            out int retryCount
            )
        {
            retryCount = properties.GetRetryNumber();

            if (!retrySettings.IsEnabled)
            {
                return(true);
            }

            if (retrySettings.DoInfinityRetries)
            {
                return(false);
            }

            return(retryCount >= retrySettings.RetryCount);
        }
        /// <summary>
        ///     Specifies the current constraint must be retried a certain amount of time
        /// </summary>
        public static IResolveConstraint Retry(this IResolveConstraint source, int count = -1, int timeGap = -1)
        {
            if (count <= 0)
            {
                count = DefaultRetryCount;
            }

            if (timeGap <= 0)
            {
                timeGap = DefaultRetryTimeGap;
            }

            var settings = new RetrySettings(retryCount: count, timeGap: timeGap);

            if (source is IConstraint constraint)
            {
                return(new RetryableWithResolveConstraintImpl(wrapped: constraint, retrySettings: settings));
            }

            return(new RetryableResolveConstraintImpl(wrapped: source, retrySettings: settings));
        }
 public SubscriberSettings Create(MqConnectionSettings mqConnectionSettings)
 {
     return(new SubscriberSettings(
                mqConnectionSettings,
                SubscriberName,
                QueueName,
                (Bindings ?? Enumerable.Empty <ExchangeBindingDto>()).Select(b => b.Create()),
                Arguments,
                UseModelTypeAsSuffix,
                ConsumerName,
                Durable,
                Exclusive,
                AutoDelete,
                AutoAck,
                UseDeadLetter,
                UsePublisherConfirms,
                TracingSettings?.Create(),
                RetrySettings?.Create(),
                ScalingSettings?.Create()
                ));
 }
Exemple #29
0
        internal static async Task RetryOperationUntilCompleted(
            Func <CallSettings, Task <bool> > fn,
            IClock clock,
            IScheduler scheduler,
            CallSettings callSettings,
            RetrySettings retrySettings)
        {
            DateTime?overallDeadline = callSettings.Expiration.CalculateDeadline(clock);

            // Every attempt should use the same deadline, calculated from the start of the call.
            if (callSettings.Expiration?.Type == ExpirationType.Timeout)
            {
                callSettings = callSettings.WithDeadline(overallDeadline.Value);
            }

            var deadlineException = new RpcException(new Status(StatusCode.DeadlineExceeded, "Deadline Exceeded"));

            foreach (var attempt in RetryAttempt.CreateRetrySequence(retrySettings, scheduler, overallDeadline, clock))
            {
                try
                {
                    bool isResponseOk = await fn(callSettings).ConfigureAwait(false);

                    if (isResponseOk)
                    {
                        return;
                    }
                    if (!attempt.ShouldRetry(deadlineException))
                    {
                        throw deadlineException;
                    }
                }
                catch (RpcException e) when(attempt.ShouldRetry(e))
                {
                    // We back off below...
                }
                await attempt.BackoffAsync(callSettings.CancellationToken.GetValueOrDefault()).ConfigureAwait(false);
            }
            throw new InvalidOperationException("Bug in GAX retry handling: finished sequence of attempts");
        }
Exemple #30
0
        internal static async Task <TResponse> Retry <TRequest, TResponse>(
            Func <TRequest, CallSettings, Task <TResponse> > fn,
            TRequest request, CallSettings callSettings, IClock clock, IScheduler scheduler)
        {
            RetrySettings retrySettings = callSettings.Timing?.Retry;

            if (retrySettings == null)
            {
                return(await fn(request, callSettings).ConfigureAwait(false));
            }
            DateTime?overallDeadline = retrySettings.TotalExpiration.CalculateDeadline(clock);
            TimeSpan retryDelay      = retrySettings.RetryBackoff.Delay;
            TimeSpan callTimeout     = retrySettings.TimeoutBackoff.Delay;

            while (true)
            {
                DateTime attemptDeadline = clock.GetCurrentDateTimeUtc() + callTimeout;
                // Note: this handles a null total deadline due to "<" returning false if overallDeadline is null.
                DateTime     combinedDeadline    = overallDeadline < attemptDeadline ? overallDeadline.Value : attemptDeadline;
                CallSettings attemptCallSettings = callSettings.WithCallTiming(CallTiming.FromDeadline(combinedDeadline));
                try
                {
                    return(await fn(request, attemptCallSettings).ConfigureAwait(false));
                }
                catch (RpcException e) when(retrySettings.RetryFilter(e))
                {
                    TimeSpan actualDelay       = retrySettings.DelayJitter.GetDelay(retryDelay);
                    DateTime expectedRetryTime = clock.GetCurrentDateTimeUtc() + actualDelay;

                    if (expectedRetryTime > overallDeadline)
                    {
                        throw;
                    }
                    await scheduler.Delay(actualDelay, callSettings.CancellationToken.GetValueOrDefault()).ConfigureAwait(false);

                    retryDelay  = retrySettings.RetryBackoff.NextDelay(retryDelay);
                    callTimeout = retrySettings.TimeoutBackoff.NextDelay(callTimeout);
                }
            }
        }
Exemple #31
0
        public async Task <Geeklist> GetGeeklist(int id, RetrySettings retrySettings, bool getComments = false)
        {
            string uri = $"{Endpoints.GET_GEEKLIST}/{id}";

            if (getComments)
            {
                uri = $"{uri}?comments=1";
            }

            HttpResponseMessage resp = await xmlRestClient.GetWithRetryAsync(uri, retrySettings);

            if (resp.StatusCode != HttpStatusCode.OK)
            {
                return(new Geeklist {
                    StatusCode = (int)resp.StatusCode
                });
            }

            _GeeklistResult result = await resp.Content.DeserializeXml <_GeeklistResult>();

            return(result.ConvertToGeeklist());
        }