public async Task ExecuteAsync_MultiplePolicies_WorkAsExpected()
        {
            // cache
            string url    = "/api/cache";
            string result = await _policyWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey1")); // typically cache key would be dynamic

            string result2 = await _policyWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey1"));

            Assert.IsTrue(!string.IsNullOrWhiteSpace(result));
            Assert.AreEqual(result, result2);

            // inner timeout (500 ms), retry (5), outer timeout (this will exception as the inner timeouts will be retried enough times to trigger outer timeout)
            url = "/api/timeout/slow";
            bool timeout = false;

            try
            {
                await _policyWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey2"));
            }
            catch (TimeoutRejectedException)
            {
                timeout = true;
            }

            Assert.IsTrue(timeout);

            // trying this again will trip circuit breaker before we get a chance to hit the outer timeout
            bool circuitIsBroken = false;

            try
            {
                string result3 = await _policyWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey3"));
            }
            catch (BrokenCircuitException)
            {
                circuitIsBroken = true;
            }

            Assert.IsTrue(circuitIsBroken);

            // lets try a fallback
            url = "/api/circuitbreaker/success";
            var fallbackWrapper = FallbackPolicy <string>
                                  .Handle <Exception>()
                                  .FallbackAsync(context => Task.Run(() => "default"))
                                  .WrapAsync(_policyWrapper);

            string result4 = await fallbackWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey4"));

            Assert.AreEqual("default", result4);

            // let circuit breaker reset
            Task.Delay(3000).Wait();
            string result5 = await fallbackWrapper.ExecuteAsync(async context => await _client.GetStringAsync(url), new Context("CacheKey5"));

            Assert.IsTrue(!string.IsNullOrWhiteSpace(result5));
            Assert.AreNotEqual("default", result5);
        }
示例#2
0
        private async Task <string> CallApiWithFallback(string action, Func <Task <string> > fallback)
        {
            var fallbackWrapper = FallbackPolicy <string>
                                  .Handle <Exception>()
                                  .FallbackAsync(context => fallback())
                                  .WrapAsync(_circuitBreaker);

            string response = await fallbackWrapper.ExecuteAsync(async context => await _client.GetStringAsync($"{_url}/{action}"), new Context());

            return(response);
        }