From 9515e8080c8341f842752d71aa3e6e66854cafc9 Mon Sep 17 00:00:00 2001 From: "HOME-LAPTOP\\kshkulev" Date: Thu, 30 Oct 2025 17:12:37 +0900 Subject: [PATCH] Refactor campaign manager --- .../CampaignManagementService.cs | 18 +-- ...tCommonRegistryElementsManager_15_7_0_1.cs | 133 +++++++++--------- .../CampaignManagers/IManager.cs | 6 +- .../CampaignManagers/ManagerBase.cs | 22 +-- .../CampaignManagers/ManagerFactory.cs | 7 +- 5 files changed, 94 insertions(+), 92 deletions(-) diff --git a/Hcs.WebApp/BackgroundServices/CampaignManagementService.cs b/Hcs.WebApp/BackgroundServices/CampaignManagementService.cs index f8bd9d5..2693b31 100644 --- a/Hcs.WebApp/BackgroundServices/CampaignManagementService.cs +++ b/Hcs.WebApp/BackgroundServices/CampaignManagementService.cs @@ -26,23 +26,14 @@ namespace Hcs.WebApp.BackgroundServices { if (stoppingToken.IsCancellationRequested) return; - using var scope = scopeFactory.CreateScope(); var manager = managerFactory.CreateManager(campaign); if (manager != null) { - try - { - await manager.StartAsync(scope); - - managers.Add(manager); - } - catch (Exception e) - { - await manager.EndWithFailAsync(scope, e); - } + managers.Add(manager); } else { + using var scope = scopeFactory.CreateScope(); var headquartersService = scope.ServiceProvider.GetRequiredService(); await headquartersService.SetCampaignEndedWithFailAsync(campaign.Id, "Не удалось найти подходящий менеджер кампании"); } @@ -50,14 +41,13 @@ namespace Hcs.WebApp.BackgroundServices foreach (var manager in managers) { - using var scope = scopeFactory.CreateScope(); try { - await manager.CheckStateAsync(scope); + await manager.ProcessAsync(); } catch (Exception e) { - await manager.EndWithFailAsync(scope, e); + await manager.EndWithFailAsync(e); } } diff --git a/Hcs.WebApp/BackgroundServices/CampaignManagers/ExportCommonRegistryElementsManager_15_7_0_1.cs b/Hcs.WebApp/BackgroundServices/CampaignManagers/ExportCommonRegistryElementsManager_15_7_0_1.cs index 07ded7f..3967474 100644 --- a/Hcs.WebApp/BackgroundServices/CampaignManagers/ExportCommonRegistryElementsManager_15_7_0_1.cs +++ b/Hcs.WebApp/BackgroundServices/CampaignManagers/ExportCommonRegistryElementsManager_15_7_0_1.cs @@ -3,40 +3,58 @@ using Hcs.WebApp.Services; namespace Hcs.WebApp.BackgroundServices.CampaignManagers { - public class ExportCommonRegistryElementsManager_15_7_0_1(OperationExecutionState operationExecutionState, ResultWaitState resultWaitState, Campaign campaign) : ManagerBase(operationExecutionState, resultWaitState, campaign) + public class ExportCommonRegistryElementsManager_15_7_0_1( + IServiceScopeFactory scopeFactory, + OperationExecutionState operationExecutionState, + ResultWaitState resultWaitState, + Campaign campaign) : ManagerBase(scopeFactory, operationExecutionState, resultWaitState, campaign) { private enum Step { Start = 0, - Execution = 1, - Wait = 2, + ExecutionWait = 1, + ResultWait = 2, End = 3 } - public override async Task StartAsync(IServiceScope scope) + private RegistryService? registryService; + + protected RegistryService RegistryService => registryService ??= scope.ServiceProvider.GetRequiredService(); + + public override async Task ProcessAsync() { - if (campaign.StartedAt.HasValue) + switch ((Step)campaign.Step) { - State = IManager.ManagerState.Started; + case Step.Start: + await DoStartStepAsync(); + break; - return; + case Step.ExecutionWait: + await DoExecutionWaitStepAsync(); + break; + + case Step.ResultWait: + await DoResultWaitStepAsync(); + break; } + } - var headquartersService = scope.ServiceProvider.GetRequiredService(); - var registryService = scope.ServiceProvider.GetRequiredService(); - using var context = headquartersService.GetNewContext(); + private async Task DoStartStepAsync() + { + IEnumerable operations; + + using var context = HeadquartersService.GetNewContext(); using var transaction = await context.Database.BeginTransactionAsync(); - IEnumerable operations = null; try { - await headquartersService.SetCampaignStartedAsync(context, campaign.Id); + await HeadquartersService.SetCampaignStartedAsync(context, campaign.Id); - campaign.Step = (int)Step.Execution; - await headquartersService.UpdateCampaignStepAsync(context, campaign); + campaign.Step = (int)Step.ExecutionWait; + await HeadquartersService.UpdateCampaignStepAsync(context, campaign); - 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); + 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(); } @@ -58,57 +76,46 @@ namespace Hcs.WebApp.BackgroundServices.CampaignManagers State = IManager.ManagerState.Started; } - public override async Task CheckStateAsync(IServiceScope scope) + private async Task DoExecutionWaitStepAsync() { - if (State == IManager.ManagerState.Started) + if (operationExecutionState.HasCampaignOperation(campaign.Id)) return; + + campaign.Step = (int)Step.ResultWait; + await HeadquartersService.UpdateCampaignStepAsync(campaign); + + var operations = await HeadquartersService.GetOperationsAsync(campaign.Id); + foreach (var operation in operations) { - switch ((Step)campaign.Step) + if (!string.IsNullOrEmpty(operation.MessageGuid)) { - case Step.Execution: - if (!operationExecutionState.HasCampaignOperation(campaign.Id)) - { - campaign.Step = (int)Step.Wait; - var headquartersService = scope.ServiceProvider.GetRequiredService(); - await headquartersService.UpdateCampaignStepAsync(campaign); - - var operations = await headquartersService.GetOperationsAsync(campaign.Id); - foreach (var operation in operations) - { - if (!string.IsNullOrEmpty(operation.MessageGuid)) - { - resultWaitState.EnqueueOperation(operation); - } - } - } - break; - - case Step.Wait: - if (!resultWaitState.HasCampaignOperation(campaign.Id)) - { - var headquartersService = scope.ServiceProvider.GetRequiredService(); - using var context = headquartersService.GetNewContext(); - using var transaction = await context.Database.BeginTransactionAsync(); - try - { - campaign.Step = (int)Step.End; - await headquartersService.UpdateCampaignStepAsync(context, campaign); - - await headquartersService.SetCampaignEndedAsync(campaign.Id); - - await transaction.CommitAsync(); - } - catch - { - transaction?.Rollback(); - - throw; - } - - State = IManager.ManagerState.Ended; - } - break; + resultWaitState.EnqueueOperation(operation); } } } + + private async Task DoResultWaitStepAsync() + { + if (resultWaitState.HasCampaignOperation(campaign.Id)) return; + + using var context = HeadquartersService.GetNewContext(); + using var transaction = await context.Database.BeginTransactionAsync(); + try + { + campaign.Step = (int)Step.End; + await HeadquartersService.UpdateCampaignStepAsync(context, campaign); + + await HeadquartersService.SetCampaignEndedAsync(campaign.Id); + + await transaction.CommitAsync(); + } + catch + { + transaction?.Rollback(); + + throw; + } + + State = IManager.ManagerState.Ended; + } } } diff --git a/Hcs.WebApp/BackgroundServices/CampaignManagers/IManager.cs b/Hcs.WebApp/BackgroundServices/CampaignManagers/IManager.cs index 7154935..20a55d6 100644 --- a/Hcs.WebApp/BackgroundServices/CampaignManagers/IManager.cs +++ b/Hcs.WebApp/BackgroundServices/CampaignManagers/IManager.cs @@ -11,10 +11,8 @@ public ManagerState State { get; } - Task StartAsync(IServiceScope scope); + Task ProcessAsync(); - Task CheckStateAsync(IServiceScope scope); - - Task EndWithFailAsync(IServiceScope scope, Exception e); + Task EndWithFailAsync(Exception e); } } diff --git a/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerBase.cs b/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerBase.cs index bbe097e..e11b52d 100644 --- a/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerBase.cs +++ b/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerBase.cs @@ -3,24 +3,30 @@ using Hcs.WebApp.Services; namespace Hcs.WebApp.BackgroundServices.CampaignManagers { - public abstract class ManagerBase(OperationExecutionState operationExecutionState, ResultWaitState resultWaitState, Campaign campaign) : IManager + public abstract class ManagerBase( + IServiceScopeFactory scopeFactory, + OperationExecutionState operationExecutionState, + ResultWaitState resultWaitState, + Campaign campaign) : IManager { + protected readonly IServiceScope scope = scopeFactory.CreateScope(); protected readonly OperationExecutionState operationExecutionState = operationExecutionState; protected readonly ResultWaitState resultWaitState = resultWaitState; protected readonly Campaign campaign = campaign; + private HeadquartersService? headquartersService; + + protected HeadquartersService HeadquartersService => headquartersService ??= scope.ServiceProvider.GetRequiredService(); + public IManager.ManagerState State { get; protected set; } = IManager.ManagerState.Created; - public abstract Task StartAsync(IServiceScope scope); + public abstract Task ProcessAsync(); - public abstract Task CheckStateAsync(IServiceScope scope); - - public async Task EndWithFailAsync(IServiceScope scope, Exception e) + public async Task EndWithFailAsync(Exception e) { - State = IManager.ManagerState.Ended; + await HeadquartersService.SetCampaignEndedWithFailAsync(campaign.Id, e.Message); - var headquartersService = scope.ServiceProvider.GetRequiredService(); - await headquartersService.SetCampaignEndedWithFailAsync(campaign.Id, e.Message); + State = IManager.ManagerState.Ended; } } } diff --git a/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerFactory.cs b/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerFactory.cs index bddf285..2666b0d 100644 --- a/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerFactory.cs +++ b/Hcs.WebApp/BackgroundServices/CampaignManagers/ManagerFactory.cs @@ -2,17 +2,18 @@ namespace Hcs.WebApp.BackgroundServices.CampaignManagers { - public class ManagerFactory(OperationExecutionState operationExecutionState, ResultWaitState resultWaitState) + public class ManagerFactory(IServiceScopeFactory serviceScopeFactory, OperationExecutionState operationExecutionState, ResultWaitState resultWaitState) { + protected readonly IServiceScopeFactory serviceScopeFactory = serviceScopeFactory; protected readonly OperationExecutionState operationExecutionState = operationExecutionState; - protected readonly ResultWaitState resultWaitState; + protected readonly ResultWaitState resultWaitState = resultWaitState; public IManager? CreateManager(Campaign campaign) { switch (campaign.Type) { case Campaign.CampaignType.ExportCommonRegistryElements_15_7_0_1: - return new ExportCommonRegistryElementsManager_15_7_0_1(operationExecutionState, resultWaitState, campaign); + return new ExportCommonRegistryElementsManager_15_7_0_1(serviceScopeFactory, operationExecutionState, resultWaitState, campaign); } return null;