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); } } }
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); } }
/// <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)); }
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)); }
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); }
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); } }
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; } }
public override Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token) => this.InnerBot.ExecuteAsync(operation, context, token);
/// <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);
public override Task ExecuteAsync(IAsyncBotOperation operation, ExecutionContext context, CancellationToken token) => operation.ExecuteAsync(context, token);