This commit is contained in:
2025-10-27 17:39:18 -04:00
commit 31f723bea4
1579 changed files with 642409 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
using Prefab.Catalog.Api.Data;
namespace Prefab.Catalog.Api.Workers;
/// <summary>
/// Background service for seeding data. Collects seed tasks from a channel and executes them concurrently.
/// </summary>
public class DataSeeder(IServiceProvider serviceProvider, IConfiguration configuration, ILogger<DataSeeder> logger) : BackgroundService
{
private readonly int _workerCount = configuration.GetValue("DataSeederWorkerCount", 4);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await WaitForDatabaseAsync(stoppingToken);
var tasks = new List<Task>();
for (var i = 0; i < _workerCount; i++)
{
tasks.Add(Task.Run(async () =>
{
await foreach (var seedTask in Prefab.Data.Seeder.Extensions.Channel.Reader.ReadAllAsync(stoppingToken))
{
try
{
await seedTask(serviceProvider, stoppingToken);
logger.LogInformation("Seed task executed successfully.");
}
catch (Exception ex)
{
logger.LogError(ex, "Error executing seed task.");
// Optionally, add retry logic here.
}
}
}, stoppingToken));
}
await Task.WhenAll(tasks);
}
private async Task WaitForDatabaseAsync(CancellationToken stoppingToken)
{
var hasLoggedWait = false;
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = serviceProvider.CreateScope();
var db = scope.ServiceProvider.GetRequiredService<AppDb>();
if (await db.Database.CanConnectAsync(stoppingToken))
{
if (hasLoggedWait)
{
logger.LogInformation("Database connectivity confirmed. Starting seed workers.");
}
return;
}
}
catch (Exception ex)
{
logger.LogDebug(ex, "Database connectivity probe failed; retrying.");
}
if (!hasLoggedWait)
{
logger.LogInformation("Waiting for database availability before processing seed tasks...");
hasLoggedWait = true;
}
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
}