test(workers): prove clock and restart safety
CI and Deploy / test (pull_request) Successful in 5m13s
CI and Deploy / deploy (pull_request) Has been skipped

This commit is contained in:
cesnimda
2026-08-15 20:18:02 +02:00
parent a08ba9b45d
commit dbf28b97ce
7 changed files with 124 additions and 36 deletions
@@ -10,7 +10,8 @@ public sealed class DailyExportHostedService(
ILogger<DailyExportHostedService> logger,
IConfiguration configuration,
AppPaths paths,
IStartupReadiness startupReadiness) : BackgroundService
IStartupReadiness startupReadiness,
TimeProvider timeProvider) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
@@ -25,11 +26,11 @@ public sealed class DailyExportHostedService(
if (hour is < 0 or > 23) hour = 2;
while (!stoppingToken.IsCancellationRequested)
{
var now = DateTime.Now;
var now = timeProvider.GetLocalNow().DateTime;
var next = new DateTime(now.Year, now.Month, now.Day, hour, 0, 0);
if (next <= now) next = next.AddDays(1);
logger.LogInformation("Next daily export scheduled at {Next}.", next);
await Task.Delay(next - now, stoppingToken);
await Task.Delay(next - now, timeProvider, stoppingToken);
await RunOnceAsync(stoppingToken);
}
}
@@ -48,12 +49,13 @@ public sealed class DailyExportHostedService(
{
var db = services.GetRequiredService<JobTrackerContext>();
var owner = db.CurrentUserId ?? throw new InvalidOperationException("Daily export requires an explicit owner scope.");
var now = timeProvider.GetLocalNow().DateTime;
var jobs = await db.JobApplications.AsNoTracking().OrderByDescending(job => job.DateApplied).ToListAsync(cancellationToken);
var jobIds = jobs.Select(job => job.Id).ToList();
var export = new
{
Version = "dailyexport.v2",
CreatedAt = DateTime.Now,
CreatedAt = now,
OwnerUserId = owner,
Companies = await db.Companies.AsNoTracking().OrderBy(company => company.Name).ToListAsync(cancellationToken),
JobApplications = jobs,
@@ -96,7 +98,7 @@ public sealed class DailyExportHostedService(
var folder = paths.GetOwnerDailyExportsRoot(configuration["Exports:DailyFolder"], owner);
Directory.CreateDirectory(folder);
var finalPath = Path.Combine(folder, $"daily_export_{DateTime.Now:yyyyMMdd}.json");
var finalPath = Path.Combine(folder, $"daily_export_{now:yyyyMMdd}.json");
var temporaryPath = finalPath + $".{Guid.NewGuid():N}.tmp";
try
{