mirror of
				https://github.com/nsnail/Ocelot.git
				synced 2025-11-04 09:15:27 +08:00 
			
		
		
		
	added docs but qos acceptance test not working seems circuit never opens but not sure if it is meant to with timeouts..investigating
This commit is contained in:
		@@ -8,7 +8,11 @@ namespace Ocelot.Configuration
 | 
			
		||||
{
 | 
			
		||||
    public class QoSOptions
 | 
			
		||||
    {
 | 
			
		||||
        public QoSOptions(int exceptionsAllowedBeforeBreaking, int durationofBreak, int timeoutValue, TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
 | 
			
		||||
        public QoSOptions(
 | 
			
		||||
            int exceptionsAllowedBeforeBreaking, 
 | 
			
		||||
            int durationofBreak, 
 | 
			
		||||
            int timeoutValue, 
 | 
			
		||||
            TimeoutStrategy timeoutStrategy = TimeoutStrategy.Pessimistic)
 | 
			
		||||
        {
 | 
			
		||||
            ExceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
 | 
			
		||||
            DurationOfBreak = TimeSpan.FromMilliseconds(durationofBreak);
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@
 | 
			
		||||
        ServicesAreNullError,
 | 
			
		||||
        ServicesAreEmptyError,
 | 
			
		||||
        UnableToFindServiceDiscoveryProviderError,
 | 
			
		||||
        UnableToFindLoadBalancerError
 | 
			
		||||
        UnableToFindLoadBalancerError,
 | 
			
		||||
        RequestTimedOutError
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -18,11 +18,17 @@ namespace Ocelot.Requester
 | 
			
		||||
        private readonly Policy _circuitBreakerPolicy;
 | 
			
		||||
        private readonly TimeoutPolicy _timeoutPolicy;
 | 
			
		||||
 | 
			
		||||
        public CircuitBreakingDelegatingHandler(int exceptionsAllowedBeforeBreaking, TimeSpan durationOfBreak,TimeSpan timeoutValue
 | 
			
		||||
            ,TimeoutStrategy timeoutStrategy, IOcelotLogger logger, HttpMessageHandler innerHandler)
 | 
			
		||||
        public CircuitBreakingDelegatingHandler(
 | 
			
		||||
            int exceptionsAllowedBeforeBreaking, 
 | 
			
		||||
            TimeSpan durationOfBreak,
 | 
			
		||||
            TimeSpan timeoutValue,
 | 
			
		||||
            TimeoutStrategy timeoutStrategy, 
 | 
			
		||||
            IOcelotLogger logger, 
 | 
			
		||||
            HttpMessageHandler innerHandler)
 | 
			
		||||
            : base(innerHandler)
 | 
			
		||||
        {
 | 
			
		||||
            this._exceptionsAllowedBeforeBreaking = exceptionsAllowedBeforeBreaking;
 | 
			
		||||
 | 
			
		||||
            this._durationOfBreak = durationOfBreak;
 | 
			
		||||
 | 
			
		||||
            _circuitBreakerPolicy = Policy
 | 
			
		||||
@@ -39,30 +45,27 @@ namespace Ocelot.Requester
 | 
			
		||||
                    onReset: () => _logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again."),
 | 
			
		||||
                    onHalfOpen: () => _logger.LogDebug(".Breaker logging: Half-open; next call is a trial.")
 | 
			
		||||
                    );
 | 
			
		||||
 | 
			
		||||
            _timeoutPolicy = Policy.TimeoutAsync(timeoutValue, timeoutStrategy);
 | 
			
		||||
 | 
			
		||||
            _logger = logger;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 | 
			
		||||
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
 | 
			
		||||
        {
 | 
			
		||||
            Task<HttpResponseMessage> responseTask = null;
 | 
			
		||||
 | 
			
		||||
            try
 | 
			
		||||
            {
 | 
			
		||||
                responseTask = Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy).ExecuteAsync<HttpResponseMessage>(() =>
 | 
			
		||||
                {
 | 
			
		||||
                    return  base.SendAsync(request,cancellationToken);
 | 
			
		||||
                });
 | 
			
		||||
                return responseTask;
 | 
			
		||||
                return await Policy.WrapAsync(_circuitBreakerPolicy, _timeoutPolicy).ExecuteAsync(() => base.SendAsync(request,cancellationToken));
 | 
			
		||||
            }
 | 
			
		||||
            catch (BrokenCircuitException ex)
 | 
			
		||||
            {
 | 
			
		||||
                _logger.LogError($"Reached to allowed number of exceptions. Circuit is open. AllowedExceptionCount: {_exceptionsAllowedBeforeBreaking}, DurationOfBreak: {_durationOfBreak}",ex);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
            catch (HttpRequestException)
 | 
			
		||||
            catch (HttpRequestException ex)
 | 
			
		||||
            {
 | 
			
		||||
                return responseTask;
 | 
			
		||||
                _logger.LogError($"Error in CircuitBreakingDelegatingHandler.SendAync", ex);
 | 
			
		||||
                throw;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ namespace Ocelot.Requester
 | 
			
		||||
                {
 | 
			
		||||
                    builder.WithCircuitBreaker(request.Qos, _logger, handler);
 | 
			
		||||
                }           
 | 
			
		||||
 | 
			
		||||
                using (var httpClient = builder.Build(handler))
 | 
			
		||||
                {
 | 
			
		||||
                    try
 | 
			
		||||
@@ -34,13 +35,14 @@ namespace Ocelot.Requester
 | 
			
		||||
                        var response = await httpClient.SendAsync(request.HttpRequestMessage);
 | 
			
		||||
                        return new OkResponse<HttpResponseMessage>(response);
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception exception)
 | 
			
		||||
                    catch (Polly.Timeout.TimeoutRejectedException exception)
 | 
			
		||||
                    {
 | 
			
		||||
                        return
 | 
			
		||||
                            new ErrorResponse<HttpResponseMessage>(new List<Error>
 | 
			
		||||
                            {
 | 
			
		||||
                                new UnableToCompleteRequestError(exception)
 | 
			
		||||
                            });
 | 
			
		||||
                           new ErrorResponse<HttpResponseMessage>(new RequestTimedOutError(exception));
 | 
			
		||||
                    }
 | 
			
		||||
                    catch (Exception exception)
 | 
			
		||||
                    {
 | 
			
		||||
                        return new ErrorResponse<HttpResponseMessage>(new UnableToCompleteRequestError(exception));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										13
									
								
								src/Ocelot/Requester/RequestTimedOutError.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/Ocelot/Requester/RequestTimedOutError.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
using System;
 | 
			
		||||
using Ocelot.Errors;
 | 
			
		||||
 | 
			
		||||
namespace Ocelot.Requester
 | 
			
		||||
{
 | 
			
		||||
    public class RequestTimedOutError : Error
 | 
			
		||||
    {
 | 
			
		||||
        public RequestTimedOutError(Exception exception) 
 | 
			
		||||
            : base($"Timeout making http request, exception: {exception.Message}", OcelotErrorCode.RequestTimedOutError)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -22,6 +22,11 @@ namespace Ocelot.Responder
 | 
			
		||||
                return new OkResponse<int>(403);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (errors.Any(e => e.Code == OcelotErrorCode.RequestTimedOutError))
 | 
			
		||||
            {
 | 
			
		||||
                return new OkResponse<int>(408);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new OkResponse<int>(404);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -5,7 +5,13 @@ namespace Ocelot.Responses
 | 
			
		||||
{
 | 
			
		||||
    public class ErrorResponse<T> : Response<T>
 | 
			
		||||
    {
 | 
			
		||||
        public ErrorResponse(List<Error> errors) : base(errors)
 | 
			
		||||
        public ErrorResponse(Error error) 
 | 
			
		||||
            : base(new List<Error> {error})
 | 
			
		||||
        {
 | 
			
		||||
            
 | 
			
		||||
        }
 | 
			
		||||
        public ErrorResponse(List<Error> errors) 
 | 
			
		||||
            : base(errors)
 | 
			
		||||
        {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user