Add caching to month summary results
This commit is contained in:
9
src/Solar.Api/Constants/CacheKeys.cs
Normal file
9
src/Solar.Api/Constants/CacheKeys.cs
Normal file
@@ -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}";
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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<SolarService>();
|
||||
builder.Services.AddMemoryCache();
|
||||
|
||||
// Database
|
||||
builder.Services.AddDbContext<DatabaseContext>(options =>
|
||||
|
||||
@@ -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<SolarService> logger;
|
||||
|
||||
public SolarService(
|
||||
DatabaseContext databaseContext,
|
||||
IMemoryCache memoryCache,
|
||||
ILogger<SolarService> 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<DaysResponse> GetDaySummaries(DateOnly start, DateOnly stop)
|
||||
{
|
||||
var zeverRecords = await databaseContext
|
||||
@@ -73,30 +92,6 @@ public class SolarService
|
||||
return new DaysResponse(logs.ToArray());
|
||||
}
|
||||
|
||||
public async Task<MonthSummariesResponse> GetMonthSummaries(int fromYear, int fromMonth, int toYear, int toMonth)
|
||||
{
|
||||
var results = new List<MonthLog>();
|
||||
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<int> GetEnvoyDayTotalWatts(DateOnly date)
|
||||
{
|
||||
var min = await databaseContext.EnvoyLogs
|
||||
@@ -116,6 +111,35 @@ public class SolarService
|
||||
return (int)(max.TotalWatts - min.TotalWatts);
|
||||
}
|
||||
|
||||
public async Task<MonthSummariesResponse> GetMonthSummaries(int fromYear, int fromMonth, int toYear, int toMonth)
|
||||
{
|
||||
var results = new List<MonthLog>();
|
||||
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<int> 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<int> 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<int> GetOrAddToCache(
|
||||
string source,
|
||||
int year,
|
||||
int month,
|
||||
Func<int, int, Task<int>> fetchMethod)
|
||||
{
|
||||
if (entities.Length < 1)
|
||||
return await memoryCache.GetOrCreateAsync(
|
||||
CacheKeys.GetMonthSummaryCacheKey(source, year, month),
|
||||
async (cacheEntry) =>
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var baseValue = entities[0].TotalWatts;
|
||||
foreach (var entity in entities)
|
||||
if (DateTime.Today.Month == month && DateTime.Today.Year == year)
|
||||
{
|
||||
entity.TotalWatts -= baseValue;
|
||||
}
|
||||
cacheEntry.SlidingExpiration = TimeSpan.FromHours(12);
|
||||
}
|
||||
return await fetchMethod(year, month);
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user