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 Microsoft.AspNetCore.Mvc;
|
||||||
using Solar.Api.Models;
|
using Solar.Api.Models;
|
||||||
using Solar.Api.Services;
|
using Solar.Api.Services;
|
||||||
using Swashbuckle.AspNetCore.Annotations;
|
using Swashbuckle.AspNetCore.Annotations;
|
||||||
|
using System.Net.Mime;
|
||||||
|
|
||||||
namespace Solar.Api.Controllers;
|
namespace Solar.Api.Controllers;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System.Text.Json;
|
|
||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
using Microsoft.OpenApi.Models;
|
using Microsoft.OpenApi.Models;
|
||||||
using Solar.Api.Converters;
|
using Solar.Api.Converters;
|
||||||
using Solar.Api.Services;
|
using Solar.Api.Services;
|
||||||
using Swashbuckle.AspNetCore.SwaggerGen;
|
using Swashbuckle.AspNetCore.SwaggerGen;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
namespace Solar.Api;
|
namespace Solar.Api;
|
||||||
|
|
||||||
@@ -15,6 +15,7 @@ public partial class Program
|
|||||||
|
|
||||||
// Services
|
// Services
|
||||||
builder.Services.AddScoped<SolarService>();
|
builder.Services.AddScoped<SolarService>();
|
||||||
|
builder.Services.AddMemoryCache();
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
builder.Services.AddDbContext<DatabaseContext>(options =>
|
builder.Services.AddDbContext<DatabaseContext>(options =>
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
using Microsoft.EntityFrameworkCore;
|
using Microsoft.EntityFrameworkCore;
|
||||||
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Solar.Api.Constants;
|
||||||
using Solar.Api.Entities;
|
using Solar.Api.Entities;
|
||||||
using Solar.Api.Models;
|
using Solar.Api.Models;
|
||||||
|
|
||||||
@@ -7,13 +9,16 @@ namespace Solar.Api.Services;
|
|||||||
public class SolarService
|
public class SolarService
|
||||||
{
|
{
|
||||||
private readonly DatabaseContext databaseContext;
|
private readonly DatabaseContext databaseContext;
|
||||||
|
private readonly IMemoryCache memoryCache;
|
||||||
private readonly ILogger<SolarService> logger;
|
private readonly ILogger<SolarService> logger;
|
||||||
|
|
||||||
public SolarService(
|
public SolarService(
|
||||||
DatabaseContext databaseContext,
|
DatabaseContext databaseContext,
|
||||||
|
IMemoryCache memoryCache,
|
||||||
ILogger<SolarService> logger)
|
ILogger<SolarService> logger)
|
||||||
{
|
{
|
||||||
this.databaseContext = databaseContext;
|
this.databaseContext = databaseContext;
|
||||||
|
this.memoryCache = memoryCache;
|
||||||
|
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
@@ -48,6 +53,20 @@ public class SolarService
|
|||||||
.ToArray());
|
.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)
|
public async Task<DaysResponse> GetDaySummaries(DateOnly start, DateOnly stop)
|
||||||
{
|
{
|
||||||
var zeverRecords = await databaseContext
|
var zeverRecords = await databaseContext
|
||||||
@@ -73,30 +92,6 @@ public class SolarService
|
|||||||
return new DaysResponse(logs.ToArray());
|
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)
|
private async Task<int> GetEnvoyDayTotalWatts(DateOnly date)
|
||||||
{
|
{
|
||||||
var min = await databaseContext.EnvoyLogs
|
var min = await databaseContext.EnvoyLogs
|
||||||
@@ -116,6 +111,35 @@ public class SolarService
|
|||||||
return (int)(max.TotalWatts - min.TotalWatts);
|
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)
|
private async Task<int> GetEnvoyMonthTotalWatts(int year, int month)
|
||||||
{
|
{
|
||||||
var min = await databaseContext.EnvoyLogs
|
var min = await databaseContext.EnvoyLogs
|
||||||
@@ -135,17 +159,21 @@ public class SolarService
|
|||||||
return (int)(max.TotalWatts - min.TotalWatts);
|
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),
|
||||||
return;
|
async (cacheEntry) =>
|
||||||
}
|
{
|
||||||
|
if (DateTime.Today.Month == month && DateTime.Today.Year == year)
|
||||||
var baseValue = entities[0].TotalWatts;
|
{
|
||||||
foreach (var entity in entities)
|
cacheEntry.SlidingExpiration = TimeSpan.FromHours(12);
|
||||||
{
|
}
|
||||||
entity.TotalWatts -= baseValue;
|
return await fetchMethod(year, month);
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user