Skip to content

Commit

Permalink
Add Circuit breaker voor ExchangeRates
Browse files Browse the repository at this point in the history
  • Loading branch information
VibeNL committed Oct 26, 2023
1 parent f9bc5fc commit c39e086
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
2 changes: 1 addition & 1 deletion ConsoleHelper/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static void Main(string[] args)
new ScalableCapitalParser(api),
new Trading212Parser(api),
});
//t.DoWork().Wait();
t.DoWork().Wait();
t = new MarketDataMaintainerTask(logger, api, cs);
t.DoWork().Wait();
}
Expand Down
19 changes: 15 additions & 4 deletions GhostfolioSidekick/Ghostfolio/API/GhostfolioAPI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,11 +148,22 @@ public async Task UpdateAccount(Model.Account account)

var sourceCurrency = mapper.MapCurrency(money.Currency.Symbol);

var content = await restCall.DoRestGet($"api/v1/exchange-rate/{sourceCurrency}-{targetCurrency.Symbol}/{date:yyyy-MM-dd}", CacheDuration.Short());
decimal rate = 1;
try
{
var content = await restCall.DoRestGet($"api/v1/exchange-rate/{sourceCurrency}-{targetCurrency.Symbol}/{date:yyyy-MM-dd}", CacheDuration.Short(), true);

dynamic stuff = JsonConvert.DeserializeObject(content);
var token = stuff.marketPrice.ToString();
var rate = (decimal)decimal.Parse(token);
if (content != null)
{
dynamic stuff = JsonConvert.DeserializeObject(content);
var token = stuff.marketPrice.ToString();
rate = (decimal)decimal.Parse(token);
}
}
catch
{
logger.LogWarning($"Exchange rate not found for {sourceCurrency}-{targetCurrency.Symbol} on {date}. Assuming rate of 1");
}

if (rate == 1)
{
Expand Down
27 changes: 25 additions & 2 deletions GhostfolioSidekick/Ghostfolio/API/RestCall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Polly;
using Polly.CircuitBreaker;
using Polly.Retry;
using RestSharp;
using System.Diagnostics;
Expand All @@ -21,6 +22,7 @@ public class RestCall
private readonly string url;
private readonly string accessToken;
private readonly RetryPolicy<RestResponse> retryPolicy;
private readonly CircuitBreakerPolicy<RestResponse> basicCircuitBreakerPolicy;

public RestCall(
IMemoryCache memoryCache,
Expand All @@ -39,15 +41,31 @@ public RestCall(
{
logger.LogDebug($"The request failed. HttpStatusCode={iRestResponse.Result.StatusCode}. Waiting {timeSpan} seconds before retry. Number attempt {retryCount}. Uri={iRestResponse.Result.ResponseUri};");
});

basicCircuitBreakerPolicy = Policy
.HandleResult<RestResponse>(r => !r.IsSuccessStatusCode)
.CircuitBreaker(2, TimeSpan.FromSeconds(30), (iRestResponse, timeSpan) =>
{
logger.LogDebug($"Circuit Breaker on a break");
}, () =>
{
logger.LogDebug($"Circuit Breaker active");
});
}

public async Task<string?> DoRestGet(string suffixUrl, MemoryCacheEntryOptions cacheEntryOptions)
public async Task<string?> DoRestGet(string suffixUrl, MemoryCacheEntryOptions cacheEntryOptions, bool useCircuitBreaker = false)
{
if (memoryCache.TryGetValue<string?>(suffixUrl, out var result))
{
return result;
}

Policy<RestResponse> policy = retryPolicy;
if (useCircuitBreaker)
{
policy = basicCircuitBreakerPolicy.Wrap(retryPolicy);
}

try
{
mutex.WaitOne();
Expand Down Expand Up @@ -75,7 +93,8 @@ public RestCall(
var stopwatch = new Stopwatch();

stopwatch.Start();
var r = retryPolicy.Execute(() => client.ExecuteGetAsync(request).Result);

var r = policy.Execute(() => client.ExecuteGetAsync(request).Result);
stopwatch.Stop();

logger.LogDebug($"Url {url}/{suffixUrl} took {stopwatch.ElapsedMilliseconds}ms");
Expand All @@ -92,6 +111,10 @@ public RestCall(

return r.Content;
}
catch (BrokenCircuitException)
{
return null;
}
finally
{
//Call the ReleaseMutex method to unblock so that other threads
Expand Down

0 comments on commit c39e086

Please sign in to comment.