From 71b6fe37a03c956822b75a24a14e37765d60520d Mon Sep 17 00:00:00 2001 From: Tijmen van Nesselrooij Date: Thu, 18 May 2023 11:49:35 +0200 Subject: [PATCH] Add caching to month summary results --- src/Solar.Api/Constants/CacheKeys.cs | 9 ++ .../Controllers/SolarLogController.cs | 2 +- src/Solar.Api/Program.cs | 3 +- src/Solar.Api/Services/SolarService.cs | 98 ++++++++++++------- 4 files changed, 75 insertions(+), 37 deletions(-) create mode 100644 src/Solar.Api/Constants/CacheKeys.cs diff --git a/src/Solar.Api/Constants/CacheKeys.cs b/src/Solar.Api/Constants/CacheKeys.cs new file mode 100644 index 0000000..d5c0c3c --- /dev/null +++ b/src/Solar.Api/Constants/CacheKeys.cs @@ -0,0 +1,9 @@ +namespace Solar.Api.Constants; + +internal static class CacheKeys +{ + public static string GetMonthSummaryCacheKey(string source, int year, int month) + { + return $"month-summary-{source}-{year}-{month}"; + } +} \ No newline at end of file diff --git a/src/Solar.Api/Controllers/SolarLogController.cs b/src/Solar.Api/Controllers/SolarLogController.cs index cf7f9a5..cf9d563 100644 --- a/src/Solar.Api/Controllers/SolarLogController.cs +++ b/src/Solar.Api/Controllers/SolarLogController.cs @@ -1,8 +1,8 @@ -using System.Net.Mime; using Microsoft.AspNetCore.Mvc; using Solar.Api.Models; using Solar.Api.Services; using Swashbuckle.AspNetCore.Annotations; +using System.Net.Mime; namespace Solar.Api.Controllers; diff --git a/src/Solar.Api/Program.cs b/src/Solar.Api/Program.cs index 3129538..4bb84b9 100644 --- a/src/Solar.Api/Program.cs +++ b/src/Solar.Api/Program.cs @@ -1,9 +1,9 @@ -using System.Text.Json; using Microsoft.EntityFrameworkCore; using Microsoft.OpenApi.Models; using Solar.Api.Converters; using Solar.Api.Services; using Swashbuckle.AspNetCore.SwaggerGen; +using System.Text.Json; namespace Solar.Api; @@ -15,6 +15,7 @@ public partial class Program // Services builder.Services.AddScoped(); + builder.Services.AddMemoryCache(); // Database builder.Services.AddDbContext(options => diff --git a/src/Solar.Api/Services/SolarService.cs b/src/Solar.Api/Services/SolarService.cs index 2c1e044..5ee17fa 100644 --- a/src/Solar.Api/Services/SolarService.cs +++ b/src/Solar.Api/Services/SolarService.cs @@ -1,4 +1,6 @@ using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Caching.Memory; +using Solar.Api.Constants; using Solar.Api.Entities; using Solar.Api.Models; @@ -7,13 +9,16 @@ namespace Solar.Api.Services; public class SolarService { private readonly DatabaseContext databaseContext; + private readonly IMemoryCache memoryCache; private readonly ILogger logger; public SolarService( DatabaseContext databaseContext, + IMemoryCache memoryCache, ILogger logger) { this.databaseContext = databaseContext; + this.memoryCache = memoryCache; this.logger = logger; } @@ -48,6 +53,20 @@ public class SolarService .ToArray()); } + private static void NormalizeEnvoyLogs(EnvoyLog[] entities) + { + if (entities.Length < 1) + { + return; + } + + var baseValue = entities[0].TotalWatts; + foreach (var entity in entities) + { + entity.TotalWatts -= baseValue; + } + } + public async Task GetDaySummaries(DateOnly start, DateOnly stop) { var zeverRecords = await databaseContext @@ -73,30 +92,6 @@ public class SolarService return new DaysResponse(logs.ToArray()); } - public async Task GetMonthSummaries(int fromYear, int fromMonth, int toYear, int toMonth) - { - var results = new List(); - var current = (Year: fromYear, Month: fromMonth); - do - { - var zeverResult = (int)await databaseContext.ZeverSummaries - .Where(zs => zs.Date.Year == current.Year && zs.Date.Month == current.Month) - .SumAsync(zs => zs.TotalWatts); - var envoyYear = await GetEnvoyMonthTotalWatts(current.Year, current.Month); - results.Add(new MonthLog(current.Year, current.Month, zeverResult, envoyYear)); - - if (current.Month == 12) - { - current = (current.Year + 1, 1); - } - else - { - current = (current.Year, current.Month + 1); - } - } while (current.Year < toYear || current.Month < toMonth); - return new MonthSummariesResponse(results.ToArray()); - } - private async Task GetEnvoyDayTotalWatts(DateOnly date) { var min = await databaseContext.EnvoyLogs @@ -116,6 +111,35 @@ public class SolarService return (int)(max.TotalWatts - min.TotalWatts); } + public async Task GetMonthSummaries(int fromYear, int fromMonth, int toYear, int toMonth) + { + var results = new List(); + var current = (Year: fromYear, Month: fromMonth); + do + { + var zeverResult = await GetOrAddToCache("zever", current.Year, current.Month, GetZeverMonthTotalWatts); + var envoyYear = await GetOrAddToCache("envoy", current.Year, current.Month, GetEnvoyMonthTotalWatts); + results.Add(new MonthLog(current.Year, current.Month, zeverResult, envoyYear)); + + if (current.Month == 12) + { + current = (current.Year + 1, 1); + } + else + { + current = (current.Year, current.Month + 1); + } + } while (current.Year < toYear || current.Month < toMonth); + return new MonthSummariesResponse(results.ToArray()); + } + + private async Task GetZeverMonthTotalWatts(int year, int month) + { + return (int)await databaseContext.ZeverSummaries + .Where(zs => zs.Date.Year == year && zs.Date.Month == month) + .SumAsync(zs => zs.TotalWatts); + } + private async Task GetEnvoyMonthTotalWatts(int year, int month) { var min = await databaseContext.EnvoyLogs @@ -135,17 +159,21 @@ public class SolarService return (int)(max.TotalWatts - min.TotalWatts); } - private static void NormalizeEnvoyLogs(EnvoyLog[] entities) + private async Task GetOrAddToCache( + string source, + int year, + int month, + Func> fetchMethod) { - if (entities.Length < 1) - { - return; - } - - var baseValue = entities[0].TotalWatts; - foreach (var entity in entities) - { - entity.TotalWatts -= baseValue; - } + return await memoryCache.GetOrCreateAsync( + CacheKeys.GetMonthSummaryCacheKey(source, year, month), + async (cacheEntry) => + { + if (DateTime.Today.Month == month && DateTime.Today.Year == year) + { + cacheEntry.SlidingExpiration = TimeSpan.FromHours(12); + } + return await fetchMethod(year, month); + }); } } \ No newline at end of file