From e58221c430f1d9493c6f9bb98a32d1d04a06b58b Mon Sep 17 00:00:00 2001 From: "HOME-LAPTOP\\kshkulev" Date: Wed, 5 Nov 2025 18:17:19 +0900 Subject: [PATCH] Change events args --- .../OperationExecutionService.cs | 18 +++++----- .../OperationExecutionState.cs | 22 +++++++----- .../ResultGetters/IResultGetter.cs | 2 +- ...xportDataProviderNsiItemGetter_15_7_0_1.cs | 18 +++++++--- .../NsiCommon/ExportNsiItemGetter_15_7_0_1.cs | 18 +++++++--- .../ResultGetters/ResultGetterBase.cs | 2 +- .../ResultGetters/ResultGetterResponse.cs | 8 +++++ .../BackgroundServices/ResultWaitService.cs | 17 +++++---- .../BackgroundServices/ResultWaitState.cs | 8 +++-- Hcs.WebApp/Components/Pages/Campaigns.razor | 36 +++++++------------ Hcs.WebApp/Services/HeadquartersService.cs | 12 +++---- 11 files changed, 96 insertions(+), 65 deletions(-) create mode 100644 Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterResponse.cs diff --git a/Hcs.WebApp/BackgroundServices/OperationExecutionService.cs b/Hcs.WebApp/BackgroundServices/OperationExecutionService.cs index 3e603ee..f26115f 100644 --- a/Hcs.WebApp/BackgroundServices/OperationExecutionService.cs +++ b/Hcs.WebApp/BackgroundServices/OperationExecutionService.cs @@ -5,7 +5,6 @@ using Hcs.WebApp.BackgroundServices.OperationExecutors; using Hcs.WebApp.Config; using Hcs.WebApp.Services; using Hcs.WebApp.Utils; -using System.Transactions; namespace Hcs.WebApp.BackgroundServices { @@ -40,25 +39,28 @@ namespace Hcs.WebApp.BackgroundServices var messageGuid = string.Empty; try { + var startedAt = DateTime.UtcNow; + await headquartersService.SetOperationStartedAsync(operation.Id, startedAt); + + state.InvokeOnOperationStarted(operation.Id, operation.CampaignId, startedAt); + var executor = executorFactory.CreateExecutor(scope, client, operation); - await headquartersService.SetOperationStartedAsync(operation.Id); - - state.InvokeOnOperationStarted(operation); - messageGuid = await executor.ExecuteAsync(stoppingToken); } catch (Exception e) { - await headquartersService.SetOperationEndedWithFailAsync(operation.Id, e.CombineMessages()); + var endedAt = DateTime.UtcNow; + var failureReason = e.CombineMessages(); + await headquartersService.SetOperationEndedWithFailAsync(operation.Id, endedAt, failureReason); - state.InvokeOnOperationEnded(operation); + state.InvokeOnOperationEnded(operation.Id, operation.CampaignId, endedAt, failureReason); } if (!string.IsNullOrEmpty(messageGuid)) { await headquartersService.SetOperationMessageGuidAsync(operation.Id, messageGuid); - state.InvokeOnOperationExecuted(operation); + state.InvokeOnOperationExecuted(operation.Id, operation.CampaignId, messageGuid); } state.UnsetProcessingOperation(operation); diff --git a/Hcs.WebApp/BackgroundServices/OperationExecutionState.cs b/Hcs.WebApp/BackgroundServices/OperationExecutionState.cs index d57c912..3d07cf1 100644 --- a/Hcs.WebApp/BackgroundServices/OperationExecutionState.cs +++ b/Hcs.WebApp/BackgroundServices/OperationExecutionState.cs @@ -5,14 +5,18 @@ namespace Hcs.WebApp.BackgroundServices { public class OperationExecutionState { + public delegate void OperationStarted(int operationId, int campaignId, DateTime startedAt); + public delegate void OperationExecuted(int operationId, int campaignId, string messageGuid); + public delegate void OperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason); + private readonly ConcurrentQueue operationsInQueue = new(); private readonly HashSet operationsInProcess = []; public bool Ready { get; set; } - public event Action OnOperationStarted; - public event Action OnOperationExecuted; - public event Action OnOperationEnded; + public event OperationStarted OnOperationStarted; + public event OperationExecuted OnOperationExecuted; + public event OperationEnded OnOperationEnded; public void EnqueueOperation(Operation operation) { @@ -39,29 +43,29 @@ namespace Hcs.WebApp.BackgroundServices return operationsInQueue.Any(x => x.CampaignId == campaignId) || operationsInProcess.Any(x => x.CampaignId == campaignId); } - public void InvokeOnOperationStarted(Operation operation) + public void InvokeOnOperationStarted(int operationId, int campaignId, DateTime startedAt) { try { - OnOperationStarted?.Invoke(operation); + OnOperationStarted?.Invoke(operationId, campaignId, startedAt); } catch { } } - public void InvokeOnOperationExecuted(Operation operation) + public void InvokeOnOperationExecuted(int operationId, int campaignId, string messageGuid) { try { - OnOperationExecuted?.Invoke(operation); + OnOperationExecuted?.Invoke(operationId, campaignId, messageGuid); } catch { } } - public void InvokeOnOperationEnded(Operation operation) + public void InvokeOnOperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason) { try { - OnOperationEnded?.Invoke(operation); + OnOperationEnded?.Invoke(operationId, campaignId, endedAt, failureReason); } catch { } } diff --git a/Hcs.WebApp/BackgroundServices/ResultGetters/IResultGetter.cs b/Hcs.WebApp/BackgroundServices/ResultGetters/IResultGetter.cs index 61fcb09..cb3d518 100644 --- a/Hcs.WebApp/BackgroundServices/ResultGetters/IResultGetter.cs +++ b/Hcs.WebApp/BackgroundServices/ResultGetters/IResultGetter.cs @@ -2,6 +2,6 @@ { public interface IResultGetter { - Task GetAsync(); + Task GetAsync(); } } diff --git a/Hcs.WebApp/BackgroundServices/ResultGetters/Nsi/ExportDataProviderNsiItemGetter_15_7_0_1.cs b/Hcs.WebApp/BackgroundServices/ResultGetters/Nsi/ExportDataProviderNsiItemGetter_15_7_0_1.cs index dff92cc..a8047a0 100644 --- a/Hcs.WebApp/BackgroundServices/ResultGetters/Nsi/ExportDataProviderNsiItemGetter_15_7_0_1.cs +++ b/Hcs.WebApp/BackgroundServices/ResultGetters/Nsi/ExportDataProviderNsiItemGetter_15_7_0_1.cs @@ -8,16 +8,21 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.Nsi { public class ExportDataProviderNsiItemGetter_15_7_0_1(IClient client, IServiceScope scope, Operation operation) : ResultGetterBase(client, scope, operation) { - public override async Task GetAsync() + public override async Task GetAsync() { var result = await client.Nsi.GetExportDataProviderNsiItemResultAsync(operation.MessageGuid!); if (!result.Ready) { - return false; + return new ResultGetterResponse() + { + success = false + }; } if (result.Success) { + DateTime endedAt = default; + var headquartersService = scope.ServiceProvider.GetRequiredService(); var registryService = scope.ServiceProvider.GetRequiredService(); @@ -47,7 +52,8 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.Nsi } await context.SaveChangesAsync(); - await headquartersService.SetOperationEndedAsync(context, operation.Id); + endedAt = DateTime.UtcNow; + await headquartersService.SetOperationEndedAsync(context, operation.Id, endedAt); await transaction.CommitAsync(); } @@ -59,7 +65,11 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.Nsi } }); - return true; + return new ResultGetterResponse() + { + success = true, + endedAt = endedAt + }; } throw Failure(result.ErrorMessage); diff --git a/Hcs.WebApp/BackgroundServices/ResultGetters/NsiCommon/ExportNsiItemGetter_15_7_0_1.cs b/Hcs.WebApp/BackgroundServices/ResultGetters/NsiCommon/ExportNsiItemGetter_15_7_0_1.cs index e3f35e6..f2726f1 100644 --- a/Hcs.WebApp/BackgroundServices/ResultGetters/NsiCommon/ExportNsiItemGetter_15_7_0_1.cs +++ b/Hcs.WebApp/BackgroundServices/ResultGetters/NsiCommon/ExportNsiItemGetter_15_7_0_1.cs @@ -8,16 +8,21 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.NsiCommon { public class ExportNsiItemGetter_15_7_0_1(IClient client, IServiceScope scope, Operation operation) : ResultGetterBase(client, scope, operation) { - public override async Task GetAsync() + public override async Task GetAsync() { var result = await client.NsiCommon.GetExportNsiItemResultAsync(operation.MessageGuid!); if (!result.Ready) { - return false; + return new ResultGetterResponse() + { + success = false + }; } if (result.Success) { + DateTime endedAt = default; + var headquartersService = scope.ServiceProvider.GetRequiredService(); var registryService = scope.ServiceProvider.GetRequiredService(); @@ -47,7 +52,8 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.NsiCommon } await context.SaveChangesAsync(); - await headquartersService.SetOperationEndedAsync(context, operation.Id); + endedAt = DateTime.UtcNow; + await headquartersService.SetOperationEndedAsync(context, operation.Id, endedAt); await transaction.CommitAsync(); } @@ -59,7 +65,11 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters.NsiCommon } }); - return true; + return new ResultGetterResponse() + { + success = true, + endedAt = endedAt + }; } throw Failure(result.ErrorMessage); diff --git a/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterBase.cs b/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterBase.cs index efee6b9..57b687d 100644 --- a/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterBase.cs +++ b/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterBase.cs @@ -10,7 +10,7 @@ namespace Hcs.WebApp.BackgroundServices.ResultGetters protected readonly IServiceScope scope = scope; protected readonly Operation operation = operation; - public abstract Task GetAsync(); + public abstract Task GetAsync(); protected Exception Failure(IErrorMessage? errorMessage) { diff --git a/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterResponse.cs b/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterResponse.cs new file mode 100644 index 0000000..c189475 --- /dev/null +++ b/Hcs.WebApp/BackgroundServices/ResultGetters/ResultGetterResponse.cs @@ -0,0 +1,8 @@ +namespace Hcs.WebApp.BackgroundServices.ResultGetters +{ + public struct ResultGetterResponse + { + public bool success; + public DateTime endedAt; + } +} diff --git a/Hcs.WebApp/BackgroundServices/ResultWaitService.cs b/Hcs.WebApp/BackgroundServices/ResultWaitService.cs index 156f796..30bf825 100644 --- a/Hcs.WebApp/BackgroundServices/ResultWaitService.cs +++ b/Hcs.WebApp/BackgroundServices/ResultWaitService.cs @@ -59,6 +59,9 @@ namespace Hcs.WebApp.BackgroundServices { entry.state.timer += ITERATION_TIME; + var endedAt = DateTime.MinValue; + var failureReason = string.Empty; + var send = entry.state.attempt switch { 0 => entry.state.timer >= 10000, @@ -72,20 +75,22 @@ namespace Hcs.WebApp.BackgroundServices try { var resultGetter = resultGetterFactory.CreateResultGetter(scope, client, entry.operation); - var success = await resultGetter.GetAsync(); - if (success) + var response = await resultGetter.GetAsync(); + if (response.success) { entry.state.done = true; + + endedAt = response.endedAt; } } catch (Exception e) { var headquartersService = scope.ServiceProvider.GetRequiredService(); - await headquartersService.SetOperationEndedWithFailAsync(entry.operation.Id, e.CombineMessages()); + endedAt = DateTime.UtcNow; + failureReason = e.CombineMessages(); + await headquartersService.SetOperationEndedWithFailAsync(entry.operation.Id, endedAt, failureReason); entry.state.done = true; - - state.InvokeOnOperationEnded(entry.operation); } entry.state.attempt++; @@ -95,7 +100,7 @@ namespace Hcs.WebApp.BackgroundServices if (entry.state.done) { state.UnsetProcessingOperation(entry.operation); - state.InvokeOnOperationEnded(entry.operation); + state.InvokeOnOperationEnded(entry.operation.Id, entry.operation.CampaignId, endedAt, failureReason); } } diff --git a/Hcs.WebApp/BackgroundServices/ResultWaitState.cs b/Hcs.WebApp/BackgroundServices/ResultWaitState.cs index 0fd59f7..354f88f 100644 --- a/Hcs.WebApp/BackgroundServices/ResultWaitState.cs +++ b/Hcs.WebApp/BackgroundServices/ResultWaitState.cs @@ -5,12 +5,14 @@ namespace Hcs.WebApp.BackgroundServices { public class ResultWaitState { + public delegate void OperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason); + private readonly ConcurrentQueue operationsInQueue = new(); private readonly HashSet operationsInProcess = []; public bool Ready { get; set; } - public event Action OnOperationEnded; + public event OperationEnded OnOperationEnded; public void EnqueueOperation(Operation operation) { @@ -37,11 +39,11 @@ namespace Hcs.WebApp.BackgroundServices return operationsInQueue.Any(x => x.CampaignId == campaignId) || operationsInProcess.Any(x => x.CampaignId == campaignId); } - public void InvokeOnOperationEnded(Operation operation) + public void InvokeOnOperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason) { try { - OnOperationEnded?.Invoke(operation); + OnOperationEnded?.Invoke(operationId, campaignId, endedAt, failureReason); } catch { } } diff --git a/Hcs.WebApp/Components/Pages/Campaigns.razor b/Hcs.WebApp/Components/Pages/Campaigns.razor index 67c811c..b7a924d 100644 --- a/Hcs.WebApp/Components/Pages/Campaigns.razor +++ b/Hcs.WebApp/Components/Pages/Campaigns.razor @@ -146,8 +146,6 @@ { targetCampaign.StartedAt = campaign.StartedAt; - StateHasChanged(); - campaignsDataGrid.Reload(); } @@ -168,8 +166,6 @@ targetCampaign.Step = campaign.Step; targetCampaign.Progress = campaign.Progress; - StateHasChanged(); - campaignsDataGrid.Reload(); if (expandedCampaign != null && expandedCampaign.Id == campaign.Id) @@ -185,18 +181,16 @@ Task.Run(RefreshCampaigns); } - void OnOperationStarted(Operation operation) + void OnOperationStarted(int operationId, int campaignId, DateTime startedAt) { InvokeAsync(() => { - if (expandedCampaign != null && expandedCampaign.Id == operation.CampaignId) + if (expandedCampaign != null && expandedCampaign.Id == campaignId) { - var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operation.Id); + var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId); if (targetOperation != null) { - targetOperation.StartedAt = operation.StartedAt; - - StateHasChanged(); + targetOperation.StartedAt = startedAt; operationsDataGrid.Reload(); } @@ -204,18 +198,16 @@ }); } - void OnOperationExecuted(Operation operation) + void OnOperationExecuted(int operationId, int campaignId, string messageGuid) { InvokeAsync(() => { - if (expandedCampaign != null && expandedCampaign.Id == operation.CampaignId) + if (expandedCampaign != null && expandedCampaign.Id == campaignId) { - var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operation.Id); + var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId); if (targetOperation != null) { - targetOperation.MessageGuid = operation.MessageGuid; - - StateHasChanged(); + targetOperation.MessageGuid = messageGuid; operationsDataGrid.Reload(); } @@ -223,19 +215,17 @@ }); } - void OnOperationEnded(Operation operation) + void OnOperationEnded(int operationId, int campaignId, DateTime endedAt, string failureReason) { InvokeAsync(() => { - if (expandedCampaign != null && expandedCampaign.Id == operation.CampaignId) + if (expandedCampaign != null && expandedCampaign.Id == campaignId) { - var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operation.Id); + var targetOperation = expandedCampaign.Operations?.FirstOrDefault(x => x.Id == operationId); if (targetOperation != null) { - targetOperation.EndedAt = operation.EndedAt; - targetOperation.FailureReason = operation.FailureReason; - - StateHasChanged(); + targetOperation.EndedAt = endedAt; + targetOperation.FailureReason = failureReason; operationsDataGrid.Reload(); } diff --git a/Hcs.WebApp/Services/HeadquartersService.cs b/Hcs.WebApp/Services/HeadquartersService.cs index 41096dd..759f11c 100644 --- a/Hcs.WebApp/Services/HeadquartersService.cs +++ b/Hcs.WebApp/Services/HeadquartersService.cs @@ -91,13 +91,13 @@ namespace Hcs.WebApp.Services } } - public async Task SetOperationStartedAsync(int operationId) + public async Task SetOperationStartedAsync(int operationId, DateTime startedAt) { using var context = GetNewContext(); var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId); if (operation != null) { - operation.StartedAt = DateTime.UtcNow; + operation.StartedAt = startedAt; await context.SaveChangesAsync(); } @@ -133,24 +133,24 @@ namespace Hcs.WebApp.Services } } - public async Task SetOperationEndedAsync(HcsDbContext context, int operationId) + public async Task SetOperationEndedAsync(HcsDbContext context, int operationId, DateTime endedAt) { var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId); if (operation != null) { - operation.EndedAt = DateTime.UtcNow; + operation.EndedAt = endedAt; await context.SaveChangesAsync(); } } - public async Task SetOperationEndedWithFailAsync(int operationId, string failureReason) + public async Task SetOperationEndedWithFailAsync(int operationId, DateTime endedAt, string failureReason) { using var context = GetNewContext(); var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId); if (operation != null) { - operation.EndedAt = DateTime.UtcNow; + operation.EndedAt = endedAt; operation.FailureReason = failureReason; await context.SaveChangesAsync();