Пример #1
0
 public void AllFeatures()
 {
     // All retry features in one method:
     Retry.Execute(() => DummyMethods.DoWork("Hello world"), TimeSpan.FromMilliseconds(100), 2,
                   DummyMethods.ExecuteOnEveryException, DummyMethods.ExecuteWhenMaxRetriesReachedBeforeExceptionIsThrown,
                   typeof(ArgumentException), typeof(DbException));
 }
Пример #2
0
        public Consignment SaveConsignment(Consignment consignment)
        {
            //Validate the object before trying to save.
            //I added a custom attribute for validating phone numbers. I only did it for phone numbers - but in reality all of the properties that needed validation would have it.
            if (!_consignmentValidator.IsValid(consignment))
            {
                return(consignment);
            }

            try
            {
                //Generic retry pattern to accomodate for failed attempts & retrying.
                //Both the delay between attempts & the amount of times to retry are stored in the appsettings.json config files
                var isSuccess = Retry.Execute(() => WriteConsignment(consignment), new TimeSpan(0, 0, _retryDelay), _retryCount, true);

                if (isSuccess)
                {
                    return(consignment);
                }

                //If after retry logic the saving of the consignment was still unsuccessful then throw an error to be caught and handled appropriately.
                throw new Exception($"Failed to save consignment after {_retryCount} attempts");
            }
            catch (Exception e)
            {
                //Log & rethrow error
                Console.WriteLine(e);
                throw;
            }
        }
Пример #3
0
        public RabbitMqPersistentConnection(
            IConfiguration configuration,
            ILogger <RabbitMqPersistentConnection> logger)
        {
            _configuration = configuration;
            _logger        = logger;

            ConnectionFactory cf = new ConnectionFactory
            {
                UserName    = _configuration["EventBusUserName"],
                Password    = _configuration["EventBusPass"],
                VirtualHost = _configuration["EventBusVirtualHost"],
                HostName    = _configuration["EventBusHostName"],
                Port        = int.Parse(_configuration["EventBusPort"])
            };

            var retry = new Retry
            {
                Log = methodName => { _logger.LogWarning($"Retiring action {methodName} in 2 sec"); }
            };

            retry.Execute(() =>
            {
                _persistentConnection = cf.CreateConnection();
            });
        }
Пример #4
0
        public void should_call_action_and_return_value()
        {
            int result = Retry.Execute(() => AddOneTime(2), TimeSpan.FromMilliseconds(100), 1);

            result.Should().Be(1);
            _timesCalled.Should().Be(2);
        }
Пример #5
0
        private void Connect()
        {
            try
            {
                Retry.Execute(() =>
                {
                    EnsureClient();

                    MyClients.Add(serviceType, m_WsDualClient);
                    client.Register(serviceType);

                    Initialize();

                    SetRequestParameters(client.GetRequestParameter(ServiceType));
                }, TimeSpan.FromSeconds(2), 1);
                InitialSuccess = true;
            }
            catch (AggregateException ex)
            {
                var msg = "连接不上服务器:" + ex.InnerExceptions.First().Message;
                MessageBox.Show(msg);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
            }
        }
        public void Retry_succeeds_if_action_succeeds()
        {
            // setup
            var retry = new Retry(TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2), 1, ex => { throw ex; });

            // execute and verify
            Assert.DoesNotThrow(() => retry.Execute(() => Task.FromResult(true)));
        }
Пример #7
0
 public void RetryWithReturnValue()
 {
     // Execute the DoWork Once (once + no retries)
     int returnValue = Retry.Execute(() =>
     {
         // Happy flow
         return(1);
     }, TimeSpan.FromMilliseconds(100), 0);
 }
Пример #8
0
 public void RetryWithoutReturnValue()
 {
     // Execute the DoWork a maximum of 3 times (once + two retries)
     Retry.Execute(() =>
     {
         // Happy flow
     },
                   TimeSpan.FromMilliseconds(100), 2);
 }
Пример #9
0
        public void should_call_action_when_final_exception_occures()
        {
            var    logger = A.Fake <ILog>();
            Action action = () => Retry.Execute(() => AddOne(100), TimeSpan.FromMilliseconds(1), 9, exception => logger.Warn(exception), exception => logger.Error(exception));

            action.ShouldThrow <NotSupportedException>();
            A.CallTo(() => logger.Error(A <Exception> .That.Matches(x => x.GetType() == typeof(AggregateException)))).MustHaveHappened(Repeated.Exactly.Times(1));
            A.CallTo(() => logger.Warn(A <Exception> .That.Matches(x => x.GetType() == typeof(NotSupportedException)))).MustHaveHappened(Repeated.Exactly.Times(10));
        }
Пример #10
0
        public void should_call_action_when_each_exception_occures()
        {
            var logger = A.Fake <ILog>();

            Retry.Execute(() => AddOne(5), TimeSpan.FromMilliseconds(100), 100, exception => logger.Warn(exception), exception => logger.Error(exception));

            A.CallTo(() => logger.Warn(A <Exception> .That.Matches(x => x.GetType() == typeof(NotSupportedException)))).MustHaveHappened(Repeated.Exactly.Times(4));
            A.CallTo(() => logger.Error(A <Exception> ._)).MustHaveHappened(Repeated.Never);
        }
Пример #11
0
        public void ExecuteTest()
        {
            int retryCount = 0;

            try
            {
                int result1 = Retry.Execute(
                    () =>
                {
                    retryCount++;
                    if (retryCount < 5)
                    {
                        throw new OperationCanceledException();
                    }

                    return(retryCount);
                },
                    3,
                    exception => exception is OperationCanceledException);
                Assert.Fail(result1.ToString());
            }
            catch (OperationCanceledException)
            {
                Assert.AreEqual(4, retryCount);
            }

            retryCount = 0;
            int result2 = Retry.Execute(() =>
            {
                retryCount++;
                if (retryCount < 5)
                {
                    throw new OperationCanceledException();
                }

                return(retryCount);
            },
                                        5,
                                        exception => exception is OperationCanceledException);

            Assert.AreEqual(5, retryCount);
            Assert.AreEqual(5, result2);

            retryCount = 0;
            int result3 = Retry.Execute(() =>
            {
                retryCount++;
                return(retryCount);
            },
                                        0,
                                        exception => exception is OperationCanceledException);

            Assert.AreEqual(1, retryCount);
        }
        public void Retry_fails_if_timeout_reached()
        {
            // setup
            int count = 0;
            var retry = new Retry(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(5), 2, e => count++);

            // execute
            var ex = Assert.Throws <AggregateException>(() => retry.Execute(() => Task.FromResult(false)));

            // verify
            count.Should().Be(3); // 1ms, 2ms, 4ms
        }
Пример #13
0
        public void should_sleep_given_timespan_between_exceptions()
        {
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            Retry.Execute(() => AddOne(4), TimeSpan.FromMilliseconds(500), 3);

            stopwatch.Stop();
            stopwatch.ElapsedMilliseconds.Should().BeGreaterOrEqualTo(1499); // Weird, should be 1500, but is sometimes faster (1499)
            // Do not sleep after last call or before first call.
            stopwatch.ElapsedMilliseconds.Should().BeLessOrEqualTo(2000);
        }
        public void Retry_collects_all_exceptions()
        {
            // setup
            var individualExceptions = new List <Exception>();
            var retry = new Retry(TimeSpan.FromMilliseconds(1), TimeSpan.FromMilliseconds(5), 2, individualExceptions.Add);

            // execute
            var ex = Assert.Throws <AggregateException>(() => retry.Execute(() => { throw new Exception(); }));

            // verify
            individualExceptions.Count.Should().Be(3); // 1ms, 2ms, 4ms
            ((AggregateException)ex.InnerExceptions[0]).InnerExceptions.Should().Equal(individualExceptions);
        }
Пример #15
0
        /// <summary>
        /// Used when you are redirected to a page
        /// </summary>
        protected TPageType GetPage <TPageType>() where TPageType : BasePage, new()
        {
            var page = new TPageType();

            page.SetLogger(Logger, Browser);

            Retry.Execute(Logger, () =>
            {
                var currentUrl = Browser.GetCurrentUrl();
                var pageUrl    = TestData.Get.GetUrl(page.UrlForPage);
                Assert.Equal(pageUrl.ToString(), currentUrl);
            });

            return(page);
        }
Пример #16
0
        public void ExecuteAsync_Failes3of3Times_Failure()
        {
            var retry        = new Retry(Enumerable.Repeat(TimeSpan.FromMilliseconds(10), 3));
            var failureCount = 0;
            var action       = new Action(() =>
            {
                if (failureCount < 3)
                {
                    failureCount++;
                    throw new Exception();
                }
            });

            Assert.ThrowsException <AggregateException>(() => retry.Execute(action));
        }
Пример #17
0
        public void ExecuteAsync_Failes2of3Times_Success()
        {
            var retry        = new Retry(Enumerable.Repeat(TimeSpan.FromMilliseconds(10), 3));
            var failureCount = 0;
            var action       = new Action(() =>
            {
                if (failureCount < 2)
                {
                    failureCount++;
                    throw new Exception();
                }
            });

            retry.Execute(action);

            Assert.AreEqual(2, failureCount);
        }
Пример #18
0
        public void ShouldRetryTwice()
        {
            int retry = 0;

            bool result = Retry.Execute(() =>
            {
                if (retry < 2)
                {
                    retry++;
                    throw new ArgumentException("Cannot connect to host");
                }

                return(true);
            }, new TimeSpan(0, 0, 1), 3, true, true);

            Assert.IsTrue(result, "Should return true after 2 failures");
            Assert.AreEqual(retry, 2);
        }
Пример #19
0
        public void EnsureDatabaseExists(string database = null, bool createDatabaseIfNotExists = true)
        {
            database = database ?? Store.Database;

            if (string.IsNullOrWhiteSpace(database))
            {
                throw new ArgumentException("Value cannot be null or whitespace.", nameof(database));
            }


            try
            {
                var retry = new Retry
                {
                    Log = methodName => { _logger.LogWarning($"Retiring action {methodName} in 2 sec"); }
                };

                retry.Execute(() => { Store.Maintenance.ForDatabase(database).Send(new GetStatisticsOperation()); });

                //Store.Maintenance.ForDatabase(database).Send(new GetStatisticsOperation());
            }
            catch (DatabaseDoesNotExistException)
            {
                if (createDatabaseIfNotExists == false)
                {
                    throw;
                }

                try
                {
                    Store.Maintenance.Server.Send(new CreateDatabaseOperation(new DatabaseRecord(database)));
                }
                catch (ConcurrencyException)
                {
                    _logger.LogError("The database was already created before calling CreateDatabaseOperation");
                }
            }
            catch (Exception e)
            {
                _logger.LogError(e.Message, e);
            }
        }
        public void Retry_tries_until_message_succeeds()
        {
            // setup
            int count = 0;
            var retry = new Retry(TimeSpan.FromMilliseconds(1), TimeSpan.MaxValue, 1, ex => { count++; });

            var results = new Queue <Task <bool> >();

            results.Enqueue(Task.FromResult(false));
            var tcs = new TaskCompletionSource <bool>();

            tcs.SetException(new Exception("foo"));
            results.Enqueue(tcs.Task);
            results.Enqueue(Task.FromResult(true));

            // execute
            retry.Execute(results.Dequeue);

            // verify
            count.Should().Be(2);
        }
Пример #21
0
        public void should_throw_exception_when_retry_is_smaller_then_zero()
        {
            Action action = () => Retry.Execute(() => AddOne(100), TimeSpan.FromMilliseconds(1), -1);

            action.ShouldThrow <ArgumentException>();
        }
Пример #22
0
        public virtual async Task ExecuteHttpCommand(IHttpCommand command,
                                                     IRetryPolicy retryPolicy            = null,
                                                     CancellationToken cancellationToken = default(CancellationToken))
        {
            if (command == null)
            {
                return;
            }
            async Task action()
            {
                try
                {
                    using (CancellationTokenSource cancellationTokenSource = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    {
                        DateTime now = DateTime.Now;
                        try // ловим таймаут
                        {
                            cancellationTokenSource.CancelAfter(command.ExpiryTime != TimeSpan.Zero ? (int)command.ExpiryTime.TotalMilliseconds : int.MaxValue);
                            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(command.Method), command.Uri);
                            //пропускаем запрос через декораторы
                            await HttpRequestPipeline(command, request, request.Properties, cancellationTokenSource.Token).ConfigureAwait(false);

                            if (cancellationTokenSource.Token.IsCancellationRequested)
                            {
                                throw new OperationCanceledException(cancellationToken);
                            }
                            //пропускаем запрос через обработчик команды
                            await command.OnExecuting(request, cancellationTokenSource.Token).ConfigureAwait(false);

                            if (cancellationTokenSource.Token.IsCancellationRequested)
                            {
                                throw new OperationCanceledException(cancellationToken);
                            }
                            HttpResponseMessage response = await _httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationTokenSource.Token).ConfigureAwait(false);

                            if (cancellationTokenSource.Token.IsCancellationRequested)
                            {
                                throw new OperationCanceledException(cancellationToken);
                            }
                            //пропускаем ответ через декораторы
                            await HttpResponsePipeline(command, response, request.Properties, cancellationTokenSource.Token).ConfigureAwait(false);

                            if (cancellationTokenSource.Token.IsCancellationRequested)
                            {
                                throw new OperationCanceledException(cancellationToken);
                            }
                            //пропускаем ответ через обработчик команды
                            await command.OnExecuted(response, cancellationTokenSource.Token).ConfigureAwait(false);

                            command.Exception = null;
                            return;
                        }
                        catch (Exception ex) //таймаут
                        {
                            if (ex is OperationCanceledException &&
                                command.ExpiryTime != TimeSpan.Zero &&
                                (now + command.ExpiryTime) < DateTime.Now)
                            {
                                throw new TimeoutException(string.Empty, ex);
                            }

                            throw;
                        }
                    }
                }
                catch (Exception ex)
                {
                    command.Exception = ex;
                    throw;
                }
            }

            if (retryPolicy == null)
            {
                await action();
            }
            else
            {
                IRetry retry = new Retry();
                await retry.Execute(action, retryPolicy, cancellationToken);
            }
        }
Пример #23
0
        public void Execute_Succeeds()
        {
            var result = Retry.Execute(() => TestMethod(), 3, new TimeSpan(0, 0, 2));

            Assert.IsTrue(result);
        }
Пример #24
0
        public void should_throw_exception_when_type_is_not_typeof_exceptions()
        {
            Action action = () => Retry.Execute(() => AddOne(100), TimeSpan.FromMilliseconds(1), 1, null, null, typeof(System.IO.DirectoryInfo), typeof(FileVersionInfo), typeof(ArgumentException));

            action.ShouldThrow <SimpleRetryArgumentException>().WithMessage("All types should be of base type exception. Found 2 type(s) that are not exceptions: DirectoryInfo, FileVersionInfo\r\nParameter name: exceptionTypesToHandle");
        }
Пример #25
0
        public void should_only_catch_given_exceptions()
        {
            Action action = () => Retry.Execute(() => AddOne(100), TimeSpan.FromMilliseconds(1), 10, null, null, typeof(DivideByZeroException));

            action.ShouldThrow <NotSupportedException>();
        }
Пример #26
0
 public void ExecuteMethodBeforeFinalExceptionIsThrown()
 {
     // Execute the DoWork and only Execute a method before the final AggregateException is thrown
     Retry.Execute(() => DummyMethods.DoWork("Hello world"), TimeSpan.FromMilliseconds(100), 2,
                   executeBeforeFinalException: DummyMethods.ExecuteWhenMaxRetriesReachedBeforeExceptionIsThrown);
 }
Пример #27
0
 public void ExecuteMethodOnEachException()
 {
     // Execute the DoWork and only Execute a method after each exception is thrown.
     Retry.Execute(() => DummyMethods.DoWork("Hello world"), TimeSpan.FromMilliseconds(100), 2,
                   executeOnEveryException: DummyMethods.ExecuteOnEveryException);
 }
Пример #28
0
 public void RetryOnlySpecificExceptions()
 {
     // Execute the DoWork and only retry with an exception that is of (base)type DbException
     Retry.Execute(() => DummyMethods.DoWork("Hello world"), TimeSpan.FromMilliseconds(100), 2,
                   exceptionTypesToHandle: new[] { typeof(ArgumentException), typeof(ArgumentOutOfRangeException) });
 }
Пример #29
0
 public void RetryOnlySpecificException()
 {
     // Execute the DoWork and only retry with an exception that is of (base)type DbException
     Retry.Execute(() => DummyMethods.DoWork("Hello world"), TimeSpan.FromMilliseconds(100), 2,
                   exceptionTypesToHandle: typeof(DbException));
 }
Пример #30
0
 public void should_catch_child_exception()
 {
     Retry.Execute(() => AddOne(2), TimeSpan.FromMilliseconds(100), 1, null, null, typeof(SystemException));
     _timesCalled.Should().Be(2);
 }