Example #1
0
        public override async Task ExecuteAsync(IAsyncBotOperation operation,
                                                ExecutionContext context, CancellationToken token)
        {
            using (var timeoutTokenSource = new CancellationTokenSource())
                using (var combinedTokenSource = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutTokenSource.Token))
                {
                    try
                    {
                        timeoutTokenSource.CancelAfter(base.Configuration.Timeout);
                        await base.InnerBot.ExecuteAsync(operation, context, combinedTokenSource.Token)
                        .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);
                    }
                    catch (Exception ex)
                    {
                        if (!timeoutTokenSource.IsCancellationRequested)
                        {
                            throw;
                        }

                        await base.Configuration.RaiseAsyncTimeoutEvent(context)
                        .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                        throw new OperationTimeoutException(Constants.TimeoutExceptionMessage, ex);
                    }
                }
        }
Example #2
0
        public override async Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token)
        {
            var shouldLimitExecution = await this.strategy.PreCheckCircuitStateAsync(token, context.BotPolicyConfiguration.ContinueOnCapturedContext)
                                       .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

            if (shouldLimitExecution && !this.executionBarrier.CompareExchange(false, true))
            {
                throw new HalfOpenExecutionLimitExceededException(Constants.HalfOpenExecutionLimitExceededExceptionMessage);
            }

            try
            {
                await base.InnerBot.ExecuteAsync(operation, context, token)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                await this.strategy.OperationSucceededAsync(token, context.BotPolicyConfiguration.ContinueOnCapturedContext)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);
            }
            catch (Exception exception)
            {
                if (base.Configuration.HandlesException(exception))
                {
                    await this.strategy.OperationFailedAsync(token, context.BotPolicyConfiguration.ContinueOnCapturedContext)
                    .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);
                }

                throw;
            }
            finally
            {
                this.executionBarrier.SetValue(false);
            }
        }
Example #3
0
        /// <inheritdoc />
        public async Task <TResult> ExecuteAsync(IAsyncBotOperation <TResult> operation, object correlationId, CancellationToken token)
        {
            Shield.EnsureNotNull(operation, nameof(operation));
            Shield.EnsureNotNull(correlationId, nameof(correlationId));

            return(await this.Bot.ExecuteAsync(operation, ExecutionContext.New(base.Configuration, correlationId), token)
                   .ConfigureAwait(base.Configuration.ContinueOnCapturedContext));
        }
Example #4
0
        public override Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token)
        {
            if (this.strategy.ShouldLimit(out var retryAfter))
            {
                throw new RateLimitExceededException(Constants.RateLimitExceededExceptionMessage, retryAfter);
            }

            return(base.InnerBot.ExecuteAsync(operation, context, token));
        }
Example #5
0
        public override async Task <TResult> ExecuteAsync(IAsyncBotOperation <TResult> operation,
                                                          ExecutionContext context, CancellationToken token)
        {
            var currentAttempt = 1;
            var tryResult      = TryResult <TResult> .Default;

            while (RetryBotUtils.ShouldExecute(tryResult, base.Configuration, currentAttempt, token))
            {
                tryResult = await this.TryAsync(operation, context, token)
                            .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                if (tryResult.IsSucceeded)
                {
                    if (currentAttempt > 1)
                    {
                        await base.Configuration.RaiseRetrySucceededEventAsync(tryResult.OperationResult, AttemptContext.New(currentAttempt, TimeSpan.Zero, context), token)
                        .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);
                    }

                    return(tryResult.OperationResult);
                }

                if (RetryBotUtils.HasMaxAttemptsReached(base.Configuration, currentAttempt))
                {
                    break;
                }

                var nextDelay = base.Configuration.CalculateNextDelay(currentAttempt, tryResult.Exception, tryResult.OperationResult);
                await base.Configuration.RaiseRetryEventAsync(tryResult.OperationResult, tryResult.Exception,
                                                              AttemptContext.New(currentAttempt, nextDelay, context), token)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                await RetryBotUtils.WaitAsync(nextDelay, context, token)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                currentAttempt++;
            }

            token.ThrowIfCancellationRequested();

            await base.Configuration.RaiseAsyncRetryLimitReachedEvent(tryResult.Exception, context, token)
            .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

            throw new MaxRetryAttemptsReachedException(Constants.MaxRetryExceptionMessage, tryResult.Exception, tryResult.OperationResult);
        }
Example #6
0
        public override async Task ExecuteAsync(IAsyncBotOperation operation,
                                                ExecutionContext context, CancellationToken token)
        {
            try
            {
                await base.InnerBot.ExecuteAsync(operation, context, token);
            }
            catch (Exception exception)
            {
                if (!base.Configuration.HandlesException(exception))
                {
                    throw;
                }

                await base.Configuration.RaiseFallbackEventAsync(exception, context, token)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);
            }
        }
Example #7
0
        private async Task <TryResult> TryAsync(
            IAsyncBotOperation operation,
            ExecutionContext context,
            CancellationToken token)
        {
            try
            {
                await base.InnerBot.ExecuteAsync(operation, context, token)
                .ConfigureAwait(context.BotPolicyConfiguration.ContinueOnCapturedContext);

                return(TryResult.Succeeded());
            }
            catch (Exception exception)
            {
                if (base.Configuration.HandlesException(exception))
                {
                    return(TryResult.Failed(exception));
                }

                throw;
            }
        }
Example #8
0
 public override Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token) =>
 this.InnerBot.ExecuteAsync(operation, context, token);
Example #9
0
 /// <summary>
 /// Executes a given operation asynchronously.
 /// </summary>
 /// <param name="operation">The operation.</param>
 /// <param name="context">The execution context which holds additional information about the current execution.</param>
 /// <param name="token">The cancellation token, used to cancel the execution of the given operation.</param>
 /// <returns>The asynchronous task which executed the operation.</returns>
 public abstract Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token);
Example #10
0
 public override Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token) =>
 operation.ExecuteAsync(context, token);