mirror of
https://github.com/nsnail/Ocelot.git
synced 2025-06-19 09:18:16 +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