using Hcs.WebApp.BackgroundServices.CampaignManagers; using Hcs.WebApp.Services; namespace Hcs.WebApp.BackgroundServices { public class CampaignManagementService( CampaignManagementState campaignManagementState, ManagerFactory managerFactory, IServiceScopeFactory scopeFactory) : BackgroundService { private const int ITERATION_TIME = 1000; private const int SLEEP_TIME = 30000; private readonly CampaignManagementState campaignManagementState = campaignManagementState; private readonly ManagerFactory managerFactory = managerFactory; private readonly IServiceScopeFactory scopeFactory = scopeFactory; private readonly List managers = []; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await InitializeStateAsync(); using var scope = scopeFactory.CreateScope(); var headquartersService = scope.ServiceProvider.GetRequiredService(); while (!stoppingToken.IsCancellationRequested) { while (campaignManagementState.TryDequeueCampaign(out var campaign)) { if (stoppingToken.IsCancellationRequested) return; try { var manager = managerFactory.CreateManager(campaign); await manager.StartAsync(stoppingToken); managers.Add(manager); } catch (Exception e) { await headquartersService.SetCampaignEndedWithFail(campaign.Id, e.Message); } } managers.RemoveAll(x => x.State == IManager.ManagerState.Ended); if (managers.Count > 0) { await Task.Delay(ITERATION_TIME, stoppingToken); } else { await Task.Delay(SLEEP_TIME, stoppingToken); } } } private async Task InitializeStateAsync() { using var scope = scopeFactory.CreateScope(); var headquartersService = scope.ServiceProvider.GetRequiredService(); var campaigns = await headquartersService.GetInitiatedCampaignAsync(); foreach (var campaign in campaigns) { campaignManagementState.EnqueueCampaign(campaign); } } } }