/// <summary> /// Create a linear retry delay of 1, 2, 3, 4s. /// </summary> /// <typeparam name="T">The type of response.</typeparam> /// <param name="option">The retry option.</param> /// <param name="context">Request context.</param> /// <param name="action">Action to execute.</param> /// <param name="predicate">Handle result predicate.</param> /// <param name="onRetry">Handle custom on retries.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public static Task <T> LinearBackoff <T>( RetryOption option, Context context, Func <Context, Task <T> > action, Func <T, bool> predicate, Action <DelegateResult <T>, TimeSpan, Context> onRetry) { if (option is null) { throw new ArgumentNullException(nameof(option)); } var delay = Backoff.LinearBackoff(TimeSpan.FromMilliseconds(option.MinDelayIsMs), retryCount: option.MaxRetry); return(HandleRetry(context, action, predicate, onRetry, delay)); }
/// <summary> /// Initializes a new instance of the <see cref="ChannelFactory"/> class. /// </summary> /// <param name="awsConnection">The details of the subscription to AWS</param> public ChannelFactory( AWSMessagingGatewayConnection awsConnection) : base(awsConnection) { _messageConsumerFactory = new SqsMessageConsumerFactory(awsConnection); var delay = Backoff.LinearBackoff(TimeSpan.FromSeconds(2), retryCount: 3, factor: 2.0, fastFirst: true); _retryPolicy = Policy .Handle <InvalidOperationException>() .WaitAndRetry(new[] { TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(5), TimeSpan.FromSeconds(10) }); }
public void Backoff_ResultIsCorrect() { // Arrange var initialDelay = TimeSpan.FromMilliseconds(10); const int retryCount = 5; const double factor = 2; const bool fastFirst = false; // Act IEnumerable <TimeSpan> result = Backoff.LinearBackoff(initialDelay, retryCount, factor, fastFirst); // Assert result.Should().NotBeNull(); result.Should().HaveCount(retryCount); result.Select(t => t.TotalMilliseconds).Should().BeEquivalentTo(new double[] { 10, 30, 50, 70, 90 }); }
/// <summary> /// Initializes a new instance of the <see cref="IdeaSearchService"/> class. /// </summary> /// <param name="optionsAccessor">A set of key/value application configuration properties.</param> /// <param name="teamIdeaStorageProvider">Team idea storage provider dependency injection.</param> /// <param name="logger">Logger implementation to send logs to the logger service.</param> /// <param name="searchServiceClient">Search service client dependency injection.</param> /// <param name="searchIndexClient">Search index client dependency injection.</param> public IdeaSearchService( IOptions <SearchServiceSettings> optionsAccessor, IIdeaStorageProvider teamIdeaStorageProvider, ILogger <IdeaSearchService> logger, SearchServiceClient searchServiceClient, SearchIndexClient searchIndexClient) { optionsAccessor = optionsAccessor ?? throw new ArgumentNullException(nameof(optionsAccessor)); this.options = optionsAccessor.Value; this.initializeTask = new Lazy <Task>(() => this.InitializeAsync()); this.teamIdeaStorageProvider = teamIdeaStorageProvider; this.logger = logger; this.searchServiceClient = searchServiceClient; this.searchIndexClient = searchIndexClient; this.retryPolicy = Policy.Handle <CloudException>( ex => (int)ex.Response.StatusCode == StatusCodes.Status409Conflict || (int)ex.Response.StatusCode == StatusCodes.Status429TooManyRequests) .WaitAndRetryAsync(Backoff.LinearBackoff(TimeSpan.FromMilliseconds(2000), 2)); }
public void Backoff_WithFactorIsZero_ResultIsConstant() { // Arrange var initialDelay = TimeSpan.FromMilliseconds(10); const int retryCount = 3; const double factor = 0; const bool fastFirst = false; // Act IEnumerable <TimeSpan> result = Backoff.LinearBackoff(initialDelay, retryCount, factor, fastFirst); // Assert result.Should().NotBeNull(); result.Should().HaveCount(retryCount); foreach (TimeSpan timeSpan in result) { timeSpan.Should().Be(initialDelay); } }
/// <summary> /// Initializes a new instance of the <see cref="PostSearchService"/> class. /// </summary> /// <param name="optionsAccessor">A set of key/value application configuration properties.</param> /// <param name="postStorageProvider">Post storage provider dependency injection.</param> /// <param name="logger">Instance to send logs to the Application Insights service.</param> /// <param name="searchServiceClient">Search service client dependency injection.</param> /// <param name="searchIndexClient">Search index client dependency injection.</param> public PostSearchService( IOptions <SearchServiceSetting> optionsAccessor, IPostStorageProvider postStorageProvider, ILogger <PostSearchService> logger, ISearchServiceClient searchServiceClient, ISearchIndexClient searchIndexClient) { optionsAccessor = optionsAccessor ?? throw new ArgumentNullException(nameof(optionsAccessor)); this.options = optionsAccessor.Value; var searchServiceValue = this.options.SearchServiceName; this.initializeTask = new Lazy <Task>(() => this.InitializeAsync()); this.postStorageProvider = postStorageProvider; this.logger = logger; this.searchServiceClient = searchServiceClient; this.searchIndexClient = searchIndexClient; this.retryPolicy = Policy.Handle <CloudException>().WaitAndRetryAsync(Backoff.LinearBackoff(TimeSpan.FromMilliseconds(2000), 2)); }