using Hcs.WebApp.Data.Hcs; using Hcs.WebApp.Services; using Microsoft.EntityFrameworkCore; namespace Hcs.WebApp.BackgroundServices.CampaignManagers { public class ExportCommonRegistryElementsManager_15_7_0_1( IServiceScopeFactory scopeFactory, OperationExecutionState operationExecutionState, ResultGetState resultGetState, DataParsingState dataParsingState, Campaign campaign) : ManagerBase(scopeFactory, operationExecutionState, resultGetState, dataParsingState, campaign) { private enum Step { Start = 0, ExecutionWait = 1, ResultWait = 2, End = 3 } private RegistryService? registryService; protected override int StepCount => Enum.GetValues(typeof(Step)).Length; protected RegistryService RegistryService => registryService ??= scope.ServiceProvider.GetRequiredService(); public override async Task ProcessAsync() { switch ((Step)campaign.Step) { case Step.Start: await DoStartStepAsync(); break; case Step.ExecutionWait: await DoExecutionWaitStepAsync(); break; case Step.ResultWait: await DoResultWaitStepAsync(); break; } } private async Task DoStartStepAsync() { DateTime startedAt = default; IEnumerable? operations = null; using var context = HeadquartersService.GetNewContext(); var executionStrategy = context.Database.CreateExecutionStrategy(); await executionStrategy.ExecuteAsync(async () => { using var transaction = await context.Database.BeginTransactionAsync(); try { startedAt = DateTime.UtcNow; await HeadquartersService.SetCampaignStartedAsync(context, campaign.Id, startedAt); await ProgressStepAsync(context, (int)Step.ExecutionWait); var registryCount = await RegistryService.GetRegistryCountAsync(context, true); operations = await HeadquartersService.InitiateOperationsAsync(context, registryCount, campaign.Id, Operation.OperationType.NsiCommon_ExportNsiItem_15_7_0_1); await RegistryService.SetOperationsToRegistriesAsync(context, true, operations); await transaction.CommitAsync(); } catch { transaction?.Rollback(); throw; } }); if (operations != null) { foreach (var operation in operations) { operationExecutionState.EnqueueOperation(operation); } } State = IManager.ManagerState.Started; InvokeOnCampaignStarted(startedAt); } private async Task DoExecutionWaitStepAsync() { if (operationExecutionState.HasCampaignOperation(campaign.Id)) return; await ProgressStepAsync((int)Step.ResultWait); var operations = await HeadquartersService.GetOperationsAsync(campaign.Id); foreach (var operation in operations) { if (!string.IsNullOrEmpty(operation.MessageGuid)) { resultGetState.EnqueueOperation(operation); } } } private async Task DoResultWaitStepAsync() { if (resultGetState.HasCampaignOperation(campaign.Id)) return; DateTime endedAt = default; using var context = HeadquartersService.GetNewContext(); var executionStrategy = context.Database.CreateExecutionStrategy(); await executionStrategy.ExecuteAsync(async () => { using var transaction = await context.Database.BeginTransactionAsync(); try { await ProgressStepAsync(context, (int)Step.End); endedAt = DateTime.UtcNow; await HeadquartersService.SetCampaignEndedAsync(context, campaign.Id, endedAt); await transaction.CommitAsync(); } catch { transaction?.Rollback(); throw; } }); State = IManager.ManagerState.Ended; InvokeOnCampaignEnded(endedAt, string.Empty); } } }