コード例 #1
0
        private async Task <TResult> HandleExceptionAsync <TResult>(Exception e, Func <Task <TResult> > func, int retries)
        {
            if (_retryStrategy.ShouldRetry(e, retries))
            {
                return(await TryAsync(func, retries + 1));
            }

            throw ApiException.CreateFromException(e);
        }
コード例 #2
0
        /// <summary>
        /// Gets a TimeSpan value which defines how long to wait before trying again after an unsuccessful attempt to
        /// dequeue a message.
        /// </summary>
        /// <param name="attempt">
        /// The number of attempts carried out so far. That is, after the first attempt (for the first retry), attempt
        /// will be set to 1, after the second attempt it is set to 2, and so on.
        /// </param>
        /// <returns>
        /// A TimeSpan value which defines how long to wait before the next attempt.
        /// </returns>
        public TimeSpan GetWaitTime(int attempt)
        {
            if (inner.ShouldRetry(attempt))
            {
                return(inner.GetWaitTime(attempt));
            }

            // We don't know the last wait time used by the inner strategy yet, so let's go and discover it.
            int lastSupportedAttempt = 1;

            while (inner.ShouldRetry(lastSupportedAttempt + 1))
            {
                lastSupportedAttempt++;
            }

            return(inner.GetWaitTime(lastSupportedAttempt));
        }
コード例 #3
0
        private TResult HandleException <TResult>(Exception e, Func <TResult> func, int retries)
        {
            if (_retryStrategy.ShouldRetry(e, retries))
            {
                return(Try(func, retries + 1));
            }

            throw e;
        }
コード例 #4
0
        public override async Task JobWasExecuted(IJobExecutionContext context, JobExecutionException jobException, CancellationToken token)
        {
            if (!_retryStrategy.ShouldRetry(context, jobException))
            {
                return;
            }

            _logger.Information("job {job} will be retried", context.JobDetail.Key);
            var trigger = _retryStrategy.GetTrigger(context);
            await context.Scheduler.UnscheduleJob(context.Trigger.Key, token);

            await context.Scheduler.ScheduleJob(context.JobDetail, trigger, token);

            return;
        }
コード例 #5
0
ファイル: Retry.cs プロジェクト: nbayles05/retrypattern
        public static T Run <T>(Func <T> func, IRetryStrategy strategy)
        {
            var failCount = 0;

            while (true)
            {
                try
                {
                    return(func.Invoke());
                }
                catch (Exception ex)
                {
                    failCount++;
                    if (!strategy.ShouldRetry(ex is AggregateException ? ex.InnerException : ex, failCount))
                    {
                        throw;
                    }
                }
                Task.Delay(strategy.NextWait(failCount));
            }
        }
コード例 #6
0
ファイル: Retry.cs プロジェクト: nbayles05/retrypattern
        public static async Task <T> RunAsync <T>(Func <Task <T> > func, IRetryStrategy strategy)
        {
            var failCount = 0;

            while (true)
            {
                try
                {
                    return(await func.Invoke().ConfigureAwait(false));
                }
                catch (Exception ex)
                {
                    failCount++;
                    if (!strategy.ShouldRetry(ex is AggregateException ? ex.InnerException : ex, failCount))
                    {
                        throw;
                    }
                }
                await Task.Delay(strategy.NextWait(failCount)).ConfigureAwait(false);
            }
        }
コード例 #7
0
ファイル: Client.cs プロジェクト: thinkingserious/StrongGrid
        private async Task <HttpResponseMessage> RequestWithRetriesAsync(Methods method, string endpoint, string content, CancellationToken cancellationToken = default(CancellationToken))
        {
            var attempts = 0;
            var response = await RequestAsync(method, endpoint, content, cancellationToken).ConfigureAwait(false);

            attempts++;

            while (_retryStrategy.ShouldRetry(attempts, response))
            {
                var timespan = _retryStrategy.GetNextDelay(attempts, response);
                if (timespan > TimeSpan.Zero)
                {
                    await Task.Delay(timespan).ConfigureAwait(false);
                }

                response = await RequestAsync(method, endpoint, content, cancellationToken).ConfigureAwait(false);

                attempts++;
            }

            return(response);
        }
コード例 #8
0
ファイル: Consumer.cs プロジェクト: rokeller/aqua
        /// <summary>
        /// Consumes one message from the queue, applying the given IRetryStrategy to wait for a message if the queue
        /// is empty.
        /// </summary>
        /// <param name="dequeueStrategy">
        /// An instance of IRetryStrategy which defines how long and how often to query the queue for a single message.
        /// </param>
        /// <param name="cancellationToken">
        /// A CancellationToken to use to check if the operation should be cancelled.
        /// </param>
        /// <returns>
        /// True if a message was successfully consumed, false otherwise.
        /// </returns>
        public bool One(IRetryStrategy dequeueStrategy, CancellationToken cancellationToken)
        {
            if (null == dequeueStrategy)
            {
                throw new ArgumentNullException("dequeueStrategy");
            }

            for (int i = 1; ; i++)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return(false);
                }

                using (JobExecutionContext context = JobExecutionContext.Dequeue(this))
                {
                    if (context.Empty)
                    {
                        if (dequeueStrategy.ShouldRetry(i))
                        {
                            Task.Delay(dequeueStrategy.GetWaitTime(i), cancellationToken)
                            .ContinueWith(NoopTaskContinuation)
                            .Wait();

                            continue;
                        }

                        break;
                    }

                    using (new JobPerfContext(this, context))
                    {
                        return(context.Execute());
                    }
                }
            }

            return(false);
        }
コード例 #9
0
        /// <summary>
        /// Sends a HTTP request to MercadoPago's APIs.
        /// </summary>
        /// <param name="request">Request data.</param>
        /// <param name="retryStrategy">Strategy to be used when it is necessary to retry the request.</param>
        /// <param name="cancellationToken">Cancellation token to cancel operation.</param>
        /// <returns>A Task with response data.</returns>
        public async Task <MercadoPagoResponse> SendAsync(
            MercadoPagoRequest request,
            IRetryStrategy retryStrategy,
            CancellationToken cancellationToken)
        {
            HttpResponseMessage httpResponse = null;
            int                numberRetries = 0;
            Exception          exception;
            HttpRequestMessage httpRequest;

            while (true)
            {
                httpRequest = CreateHttpRequest(request);

                try
                {
                    httpResponse = await HttpClient.SendAsync(httpRequest,
                                                              HttpCompletionOption.ResponseHeadersRead,
                                                              cancellationToken).ConfigureAwait(false);

                    exception = null;
                }
                catch (Exception ex)
                {
                    exception = ex;
                }

                RetryResponse retryResponse = retryStrategy.ShouldRetry(
                    httpRequest,
                    httpResponse,
                    IsRetryableError(exception, cancellationToken),
                    numberRetries);

                if (!retryResponse.Retry)
                {
                    break;
                }

                // Dispose HTTP response if if will retry
                if (httpResponse != null)
                {
                    httpResponse.Dispose();
                }

                numberRetries++;
                await Task.Delay(retryResponse.Delay).ConfigureAwait(false);
            }

            // Dispose HTTP request
            if (httpRequest != null)
            {
                httpRequest.Dispose();
            }

            if (exception != null)
            {
                throw exception;
            }

            return(await MapResponse(httpResponse));
        }
コード例 #10
0
ファイル: Consumer.cs プロジェクト: rokeller/aqua
        /// <summary>
        /// Consumes one message from the queue, applying the given IRetryStrategy to wait for a message if the queue
        /// is empty.
        /// </summary>
        /// <param name="dequeueStrategy">
        /// An instance of IRetryStrategy which defines how long and how often to query the queue for a single message.
        /// </param>
        /// <param name="cancellationToken">
        /// A CancellationToken to use to check if the operation should be cancelled.
        /// </param>
        /// <returns>
        /// True if a message was successfully consumed, false otherwise.
        /// </returns>
        public bool One(IRetryStrategy dequeueStrategy, CancellationToken cancellationToken)
        {
            if (null == dequeueStrategy)
            {
                throw new ArgumentNullException("dequeueStrategy");
            }

            for (int i = 1; ; i++)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return false;
                }

                using (JobExecutionContext context = JobExecutionContext.Dequeue(this))
                {
                    if (context.Empty)
                    {
                        if (dequeueStrategy.ShouldRetry(i))
                        {
                            Task.Delay(dequeueStrategy.GetWaitTime(i), cancellationToken)
                                .ContinueWith(NoopTaskContinuation)
                                .Wait();

                            continue;
                        }

                        break;
                    }

                    return context.Execute();
                }
            }

            return false;
        }
コード例 #11
0
 /// <summary>
 /// Checks if we should retry after an unsuccessful attempt to dequeue a message.
 /// </summary>
 /// <param name="attempt">
 /// The number of attempts carried out so far. That is, after the first attempt (for the first retry), attempt
 /// will be set to 1, after the second attempt it is set to 2, and so on.
 /// </param>
 /// <returns>
 /// True if another attempt to dequeue a message should be made, false otherwise.
 /// </returns>
 public bool ShouldRetry(int attempt)
 {
     return(inner.ShouldRetry(attempt));
 }
コード例 #12
0
 bool WillRetry(Exception e, IEnumerator <TimeSpan> delays) =>
 delays.MoveNext() && _retryStrategy.ShouldRetry(e);