Skip to content

Commit

Permalink
Merge pull request #219 from code4romania/bugfix/fix-cache-issues
Browse files Browse the repository at this point in the history
try fixing api
  • Loading branch information
idormenco authored Jul 8, 2024
2 parents e3deb7b + 2285495 commit ec7cd2a
Show file tree
Hide file tree
Showing 13 changed files with 157 additions and 207 deletions.
137 changes: 78 additions & 59 deletions src/ElectionResults.API/Controllers/BallotsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,14 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ElectionResults.API.Options;
using CSharpFunctionalExtensions;
using ElectionResults.Core.Elections;
using ElectionResults.Core.Endpoints.Query;
using ElectionResults.Core.Endpoints.Response;
using ElectionResults.Core.Infrastructure;
using ElectionResults.Core.Repositories;
using LazyCache;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using ZiggyCreatures.Caching.Fusion;

namespace ElectionResults.API.Controllers
{
Expand All @@ -19,27 +18,27 @@ namespace ElectionResults.API.Controllers
public class BallotsController : ControllerBase
{
private readonly IResultsAggregator _resultsAggregator;
private readonly IAppCache _appCache;
private readonly ITerritoryRepository _territoryRepository;
private readonly MemoryCacheSettings _cacheSettings;
private readonly IFusionCache _fusionCache;

public BallotsController(IResultsAggregator resultsAggregator,
IAppCache appCache,
ITerritoryRepository territoryRepository,
IOptions<MemoryCacheSettings> cacheSettings)
IFusionCache fusionCache)
{
_resultsAggregator = resultsAggregator;
_appCache = appCache;
_territoryRepository = territoryRepository;
_cacheSettings = cacheSettings.Value;
_fusionCache = fusionCache;
}

[HttpGet("ballots")]
public async Task<ActionResult<List<ElectionMeta>>> GetBallots()
{
var result = await _appCache.GetOrAddAsync(
"ballots", async () => await _resultsAggregator.GetAllBallots(),
DateTimeOffset.Now.AddMinutes(120));
var result = await _fusionCache.GetOrSetAsync<Result<List<ElectionMeta>>>("ballots", async (ctx, ct) =>
{
var result = await _resultsAggregator.GetAllBallots();
ctx.Options.Duration = TimeSpan.FromMinutes(result.IsFailure ? 1 : 10);
return result;
});

if (result.IsSuccess)
{
Expand Down Expand Up @@ -72,15 +71,18 @@ public async Task<ActionResult<List<PartyList>>> GetCandidatesForBallot([FromQue
query.Round = null;
}

var result = await _appCache.GetOrAddAsync(
query.GetCacheKey(), async () => await _resultsAggregator.GetBallotCandidates(query),
DateTimeOffset.Now.AddMinutes(query.GetCacheDurationInMinutes()));
var result = await _fusionCache.GetOrSetAsync<Result<List<PartyList>>>(query.GetCacheKey("candidates"),
async (ctx, ct) =>
{
var result = await _resultsAggregator.GetBallotCandidates(query);
ctx.Options.Duration = TimeSpan.FromMinutes(result.IsFailure ? 1 : 10);
return result;
});

return result.Value;
}
catch (Exception e)
{
_appCache.Remove(query.GetCacheKey());
Log.LogError(e, "Exception encountered while retrieving voter turnout stats");
return StatusCode(500, e.StackTrace);
}
Expand All @@ -106,11 +108,19 @@ public async Task<ActionResult<ElectionResponse>> GetBallot([FromQuery] Election
query.Round = null;
}

var expiration = GetExpirationDate(query);
var result = await _fusionCache.GetOrSetAsync<Result<ElectionResponse>>(query.GetCacheKey("ballot"),
async (ctx, ct) =>
{
var result = await _resultsAggregator.GetBallotResults(query);
ctx.Options.Duration =
TimeSpan.FromMinutes(result.IsFailure ? 1 : query.BallotId <= 113 ? 1440 : 10);
return result;
});

var result = await _appCache.GetOrAddAsync(
query.GetCacheKey(), async () => await _resultsAggregator.GetBallotResults(query),
expiration);
if (result.IsFailure)
{
return StatusCode(500, result.Error);
}

var newsFeed = await _resultsAggregator.GetNewsFeed(query, result.Value.Meta.ElectionId);
result.Value.ElectionNews = newsFeed;
Expand All @@ -119,7 +129,6 @@ public async Task<ActionResult<ElectionResponse>> GetBallot([FromQuery] Election
}
catch (Exception e)
{
_appCache.Remove(query.GetCacheKey());
Log.LogError(e, "Exception encountered while retrieving voter turnout stats");
return StatusCode(500, e.StackTrace);
}
Expand All @@ -128,81 +137,91 @@ public async Task<ActionResult<ElectionResponse>> GetBallot([FromQuery] Election
[HttpGet("counties")]
public async Task<ActionResult<List<LocationData>>> GetCounties()
{
try
{
var countiesResult = await _territoryRepository.GetCounties();
if (countiesResult.IsSuccess)
var result = await _fusionCache.GetOrSetAsync<Result<List<LocationData>>>("counties",
async (ctx, ct) =>
{
var countiesResult = await _territoryRepository.GetCounties();
ctx.Options.Duration = TimeSpan.FromMinutes(countiesResult.IsFailure ? 1 : 1440);

if (countiesResult.IsFailure)
{
return Result.Failure<List<LocationData>>(countiesResult.Error);
}

return countiesResult.Value.Select(c => new LocationData
{
Id = c.CountyId,
Name = c.Name
}).ToList();
}
});

return StatusCode(500, countiesResult.Error);
}
catch (Exception e)
if (result.IsFailure)
{
return StatusCode(500, e.Message);
return StatusCode(500, result.Error);
}

return result.Value;
}

[HttpGet("localities")]
public async Task<ActionResult<List<LocationData>>> GetLocalities([FromQuery] int? countyId, int? ballotId)
{
try
{
var result = await _territoryRepository.GetLocalities(countyId, ballotId);
if (result.IsSuccess)
var result = await _fusionCache.GetOrSetAsync<Result<List<LocationData>>>(
$"localities-{ballotId}-{countyId}",
async (ctx, ct) =>
{
return result.Value.Select(c => new LocationData
var localitiesResult = await _territoryRepository.GetLocalities(countyId, ballotId);
ctx.Options.Duration = TimeSpan.FromMinutes(localitiesResult.IsFailure ? 1 : 1440);

if (localitiesResult.IsFailure)
{
return Result.Failure<List<LocationData>>(localitiesResult.Error);
}

return localitiesResult.Value.Select(c => new LocationData
{
Id = c.LocalityId,
Name = c.Name,
CountyId = c.CountyId
}).ToList();
}
});

return StatusCode(500, result.Error);
}
catch (Exception e)
if (result.IsFailure)
{
return StatusCode(500, e.Message);
return StatusCode(500, result.Error);
}

return result.Value;
}

[HttpGet("countries")]
public async Task<ActionResult<List<LocationData>>> GetCountries([FromQuery] int? ballotId)
{
try
{
var result = await _territoryRepository.GetCountries(ballotId);
if (result.IsSuccess)
var result = await _fusionCache.GetOrSetAsync<Result<List<LocationData>>>(
$"countries-{ballotId}",
async (ctx, ct) =>
{
return result.Value.Select(c => new LocationData
var countriesResult = await _territoryRepository.GetCountries(ballotId);
ctx.Options.Duration = TimeSpan.FromMinutes(countriesResult.IsFailure ? 1 : 1440);

if (countriesResult.IsFailure)
{
return Result.Failure<List<LocationData>>(countriesResult.Error);
}

return countriesResult.Value.Select(c => new LocationData
{
Id = c.Id,
Name = c.Name
}).ToList();
}

return StatusCode(500, result.Error);
}
catch (Exception e)
{
return StatusCode(500, e.Message);
}
}
});

private DateTimeOffset GetExpirationDate(ElectionResultsQuery electionResultsQuery)
{
if (electionResultsQuery.BallotId <= 113) // ballot older than parliament elections in 2020
if (result.IsFailure)
{
return DateTimeOffset.Now.AddDays(1);
return StatusCode(500, result.Error);
}

return DateTimeOffset.Now.AddMinutes(1);
return result.Value;
}
}
}
2 changes: 1 addition & 1 deletion src/ElectionResults.API/ElectionResults.API.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.2" />
<PackageReference Include="ZiggyCreatures.FusionCache" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ElectionResults.Core\ElectionResults.Core.csproj" />
Expand All @@ -33,7 +34,6 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Import\" />
<Folder Include="Options\" />
<Folder Include="wwwroot\lib\" />
<Folder Include="wwwroot\upload\" />
</ItemGroup>
Expand Down
8 changes: 0 additions & 8 deletions src/ElectionResults.API/Options/CacheSettings.cs

This file was deleted.

6 changes: 2 additions & 4 deletions src/ElectionResults.API/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using ElectionResults.API.Converters;
using ElectionResults.API.Options;
using ElectionResults.Core.Configuration;
using ElectionResults.Core.Elections;
using ElectionResults.Core.Infrastructure;
Expand Down Expand Up @@ -51,7 +50,7 @@ public void ConfigureServices(IServiceCollection services)
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter(new SnakeCaseNamingPolicy()));
});
services.AddLazyCache();

RegisterDependencies(services, Configuration);
services.AddSwaggerGen(c =>
{
Expand All @@ -65,7 +64,6 @@ public void ConfigureServices(IServiceCollection services)
options.UseMySQL(connectionString);
});

services.AddLazyCache();
services.AddCors(options =>
{
options.AddPolicy("origins",
Expand All @@ -79,6 +77,7 @@ public void ConfigureServices(IServiceCollection services)
});

services.AddHealthChecks();
services.AddFusionCache();
}

private static void RegisterDependencies(IServiceCollection services, IConfiguration configuration)
Expand All @@ -96,7 +95,6 @@ private static void RegisterDependencies(IServiceCollection services, IConfigura
services.AddScoped<IPartiesRepository, PartiesRepository>();

services.Configure<AWSS3Settings>(configuration.GetSection(AWSS3Settings.SectionKey));
services.Configure<MemoryCacheSettings>(configuration.GetSection(MemoryCacheSettings.SectionKey));
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, ApplicationDbContext context, ILoggerFactory loggerFactory)
Expand Down
4 changes: 1 addition & 3 deletions src/ElectionResults.Core/ElectionResults.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
<PackageReference Include="CSharpFunctionalExtensions" Version="2.42.0" />
<PackageReference Include="CsvHelper" Version="32.0.3" />
<PackageReference Include="Diacritics" Version="3.3.29" />
<PackageReference Include="LazyCache" Version="2.4.0" />
<PackageReference Include="LazyCache.AspNetCore" Version="2.4.0" />
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.2.0" />
<PackageReference Include="Humanizer" Version="2.14.1" />
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.6" />
Expand All @@ -24,7 +22,7 @@
<PackageReference Include="Microsoft.Extensions.Options" Version="8.0.2" />
<PackageReference Include="MySql.EntityFrameworkCore" Version="8.0.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="Z.EntityFramework.Extensions.EFCore" Version="8.102.2.5" />
<PackageReference Include="Z.EntityFramework.Plus.EFCore" Version="8.103.0" />
</ItemGroup>

</Project>
Loading

0 comments on commit ec7cd2a

Please sign in to comment.