Skip to content
This repository has been archived by the owner on Jan 8, 2019. It is now read-only.

Commit

Permalink
Merge pull request #2 from ThreeMammals/feature/moveing-polly-code-fr…
Browse files Browse the repository at this point in the history
…om-ocelot

Feature/moveing polly code from ocelot
  • Loading branch information
TomPallister authored Aug 19, 2018
2 parents cc02370 + ebc802b commit 81df8b7
Show file tree
Hide file tree
Showing 21 changed files with 690 additions and 19 deletions.
3 changes: 2 additions & 1 deletion Ocelot.Provider.Polly.sln
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Microsoft Visual Studio Solution File, Format Version 12.00

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.27130.2036
MinimumVisualStudioVersion = 10.0.40219.1
Expand Down
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
[<img src="http://threemammals.com/images/ocelot_logo.png">](http://threemammals.com/ocelot)

[![Build status](https://ci.appveyor.com/api/projects/status/8ry4ailt7rr5mbu7?svg=true)](https://ci.appveyor.com/project/TomPallister/ocelot-cache-cachemanager)
Windows (AppVeyor)
[![Build Status](https://travis-ci.org/ThreeMammals/Ocelot.Provider.Polly.svg?branch=master)](https://travis-ci.org/ThreeMammals/Ocelot.Provider.Polly) Linux & OSX (Travis)
[![Build status](https://ci.appveyor.com/api/projects/status/64dld693t29wgikc?svg=true)](https://ci.appveyor.com/project/TomPallister/ocelot-provider-polly) Windows (AppVeyor)
[![Build Status](https://travis-ci.org/ThreeMammals/Ocelot.Provider.Polly.svg?branch=develop)](https://travis-ci.org/ThreeMammals/Ocelot.Provider.Polly) Linux & OSX (Travis)

[![Coverage Status](https://coveralls.io/repos/github/ThreeMammals/Ocelot.Provider.Polly/badge.svg?branch=develop)](https://coveralls.io/github/ThreeMammals/Ocelot.Provider.Polly?branch=develop)
[![Coverage Status](https://coveralls.io/repos/github/ThreeMammals/Ocelot.Provider.Polly/badge.svg)](https://coveralls.io/github/ThreeMammals/Ocelot.Provider.Polly)

# Ocelot

Expand Down
17 changes: 17 additions & 0 deletions src/Ocelot.Provider.Polly/CircuitBreaker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using Polly.CircuitBreaker;
using Polly.Timeout;

namespace Ocelot.Provider.Polly
{
public class CircuitBreaker
{
public CircuitBreaker(CircuitBreakerPolicy circuitBreakerPolicy, TimeoutPolicy timeoutPolicy)
{
CircuitBreakerPolicy = circuitBreakerPolicy;
TimeoutPolicy = timeoutPolicy;
}

public CircuitBreakerPolicy CircuitBreakerPolicy { get; private set; }
public TimeoutPolicy TimeoutPolicy { get; private set; }
}
}
5 changes: 3 additions & 2 deletions src/Ocelot.Provider.Polly/Ocelot.Provider.Polly.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>
<NETStandardImplicitPackageVersion>2.0.0</NETStandardImplicitPackageVersion>
<NoPackageAnalysis>true</NoPackageAnalysis>
<Description>Provides Ocelot extensions to use CacheManager.Net</Description>
<Description>Provides Ocelot extensions to use Polly.NET</Description>
<AssemblyTitle>Ocelot.Provider.Polly</AssemblyTitle>
<VersionPrefix>0.0.0-dev</VersionPrefix>
<AssemblyName>Ocelot.Provider.Polly</AssemblyName>
Expand All @@ -26,9 +26,10 @@
<DebugSymbols>True</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Ocelot" Version="10.0.2" />
<PackageReference Include="Ocelot" Version="10.0.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="Polly" Version="6.0.1" />
</ItemGroup>
</Project>
28 changes: 27 additions & 1 deletion src/Ocelot.Provider.Polly/OcelotBuilderExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,37 @@
namespace Ocelot.Provider.Polly
{
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Configuration;
using DependencyInjection;
using Errors;
using global::Polly.CircuitBreaker;
using global::Polly.Timeout;
using Logging;
using Microsoft.Extensions.DependencyInjection;
using Requester;

public static class OcelotBuilderExtensions
{
public static IOcelotBuilder AddSomething(this IOcelotBuilder builder)
public static IOcelotBuilder AddPolly(this IOcelotBuilder builder)
{
var errorMapping = new Dictionary<Type, Func<Exception, Error>>
{
{typeof(TaskCanceledException), e => new RequestTimedOutError(e)},
{typeof(TimeoutRejectedException), e => new RequestTimedOutError(e)},
{typeof(BrokenCircuitException), e => new RequestTimedOutError(e)}
};

builder.Services.AddSingleton(errorMapping);

DelegatingHandler QosDelegatingHandlerDelegate(DownstreamReRoute reRoute, IOcelotLoggerFactory logger)
{
return new PollyCircuitBreakingDelegatingHandler(new PollyQoSProvider(reRoute, logger), logger);
}

builder.Services.AddSingleton((QosDelegatingHandlerDelegate) QosDelegatingHandlerDelegate);
return builder;
}
}
Expand Down
43 changes: 43 additions & 0 deletions src/Ocelot.Provider.Polly/PollyCircuitBreakingDelegatingHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using Ocelot.Logging;
using Polly;
using Polly.CircuitBreaker;

namespace Ocelot.Provider.Polly
{
public class PollyCircuitBreakingDelegatingHandler : DelegatingHandler
{
private readonly PollyQoSProvider _qoSProvider;
private readonly IOcelotLogger _logger;

public PollyCircuitBreakingDelegatingHandler(
PollyQoSProvider qoSProvider,
IOcelotLoggerFactory loggerFactory)
{
_qoSProvider = qoSProvider;
_logger = loggerFactory.CreateLogger<PollyCircuitBreakingDelegatingHandler>();
}

protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
try
{
return await Policy
.WrapAsync(_qoSProvider.CircuitBreaker.CircuitBreakerPolicy, _qoSProvider.CircuitBreaker.TimeoutPolicy)
.ExecuteAsync(() => base.SendAsync(request,cancellationToken));
}
catch (BrokenCircuitException ex)
{
_logger.LogError($"Reached to allowed number of exceptions. Circuit is open",ex);
throw;
}
catch (HttpRequestException ex)
{
_logger.LogError($"Error in CircuitBreakingDelegatingHandler.SendAync", ex);
throw;
}
}
}
}
52 changes: 52 additions & 0 deletions src/Ocelot.Provider.Polly/PollyQoSProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
namespace Ocelot.Provider.Polly
{
using System;
using System.Net.Http;
using global::Polly;
using global::Polly.CircuitBreaker;
using global::Polly.Timeout;
using Ocelot.Configuration;
using Ocelot.Logging;

public class PollyQoSProvider
{
private readonly CircuitBreakerPolicy _circuitBreakerPolicy;
private readonly TimeoutPolicy _timeoutPolicy;
private readonly IOcelotLogger _logger;

public PollyQoSProvider(DownstreamReRoute reRoute, IOcelotLoggerFactory loggerFactory)
{
_logger = loggerFactory.CreateLogger<PollyQoSProvider>();

Enum.TryParse(reRoute.QosOptions.TimeoutStrategy, out TimeoutStrategy strategy);

_timeoutPolicy = Policy.TimeoutAsync(TimeSpan.FromMilliseconds(reRoute.QosOptions.TimeoutValue), strategy);

_circuitBreakerPolicy = Policy
.Handle<HttpRequestException>()
.Or<TimeoutRejectedException>()
.Or<TimeoutException>()
.CircuitBreakerAsync(
exceptionsAllowedBeforeBreaking: reRoute.QosOptions.ExceptionsAllowedBeforeBreaking,
durationOfBreak: TimeSpan.FromMilliseconds(reRoute.QosOptions.DurationOfBreak),
onBreak: (ex, breakDelay) =>
{
_logger.LogError(
".Breaker logging: Breaking the circuit for " + breakDelay.TotalMilliseconds + "ms!", ex);
},
onReset: () =>
{
_logger.LogDebug(".Breaker logging: Call ok! Closed the circuit again.");
},
onHalfOpen: () =>
{
_logger.LogDebug(".Breaker logging: Half-open; next call is a trial.");
}
);

CircuitBreaker = new CircuitBreaker(_circuitBreakerPolicy, _timeoutPolicy);
}

public CircuitBreaker CircuitBreaker { get; }
}
}
13 changes: 13 additions & 0 deletions src/Ocelot.Provider.Polly/RequestTimedOutError.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Ocelot.Provider.Polly
{
using System;
using Errors;

public class RequestTimedOutError : Error
{
public RequestTimedOutError(Exception exception)
: base($"Timeout making http request, exception: {exception}", OcelotErrorCode.RequestTimedOutError)
{
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
<PackageReference Include="Microsoft.AspNetCore.All" Version="2.1.1" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="2.1.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.7.2" />
<PackageReference Include="Ocelot" Version="10.0.2" />
<PackageReference Include="Ocelot" Version="10.0.3" />
<PackageReference Include="StyleCop.Analyzers" Version="1.0.2">
<PrivateAssets>all</PrivateAssets>
</PackageReference>
Expand Down
Loading

0 comments on commit 81df8b7

Please sign in to comment.