Start operation implementation

This commit is contained in:
2025-10-23 18:15:25 +09:00
parent 0626ce0176
commit 608dcc2098
5 changed files with 97 additions and 3 deletions

View File

@ -0,0 +1,17 @@
namespace Hcs.WebApp.BackgroundServices
{
public class OperationExecutionService(OperationExecutionState state) : BackgroundService
{
private readonly OperationExecutionState state = state;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(10000, stoppingToken);
// TODO
}
}
}
}

View File

@ -0,0 +1,27 @@
using Hcs.WebApp.Data.Hcs;
using System.Collections.Concurrent;
namespace Hcs.WebApp.BackgroundServices
{
public class OperationExecutionState
{
private readonly ConcurrentQueue<Operation> operations = new();
public event Action<Operation> OnOperationStarted;
public void EnqueueOperation(Operation operation)
{
operations.Enqueue(operation);
}
public bool TryDequeueOperation(out Operation operation)
{
return operations.TryDequeue(out operation);
}
public void InvokeOnOperationStarted(Operation operation)
{
OnOperationStarted?.Invoke(operation);
}
}
}

View File

@ -1,18 +1,22 @@
@page "/registry/common"
@using System.IdentityModel.Claims
@using Hcs.WebApp.BackgroundServices
@using Hcs.WebApp.Components.Dialogs
@using Hcs.WebApp.Services
@using Microsoft.AspNetCore.Authorization
@using Microsoft.AspNetCore.Identity
@using Microsoft.EntityFrameworkCore
@implements IDisposable
@attribute [Authorize]
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject OperationService OperationService
@inject RegistryService RegistryService
@inject DialogService DialogService
@inject OperationExecutionState OperationExecutionState
<PageTitle>Общие справочники подсистемы НСИ</PageTitle>
@ -74,7 +78,6 @@
if (firstRender)
{
ChangeState(CommonPageState.Init);
StateHasChanged();
var finalState = CommonPageState.Idle;
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
@ -89,16 +92,29 @@
{
registries = await RegistryService.GetAllRegistries(true);
}
OperationExecutionState.OnOperationStarted += OnOperationStarted;
}
ChangeState(finalState);
StateHasChanged();
}
}
async Task SyncRegistries()
{
// TODO
if (state == CommonPageState.OperationWaiting) return;
ChangeState(CommonPageState.OperationWaiting);
if (await OperationService.HasActiveOperation(Operation.OperationType.Nsi_15_7_0_1_ExportAllRegistryElements))
{
ChangeState(CommonPageState.Idle);
}
else
{
var operation = await OperationService.InitiateOperation(Operation.OperationType.Nsi_15_7_0_1_ExportAllRegistryElements, "");
OperationExecutionState.EnqueueOperation(operation);
}
}
async Task ViewRegistry(Registry userWithRole)
@ -118,9 +134,12 @@
void ChangeState(CommonPageState state)
{
if (this.state == state) return;
this.state = state;
SetSyncText();
StateHasChanged();
}
void SetSyncText()
@ -141,4 +160,17 @@
break;
}
}
void OnOperationStarted(Operation operation)
{
if (operation.Type == Operation.OperationType.Nsi_15_7_0_1_ExportAllRegistryElements)
{
InvokeAsync(() => ChangeState(CommonPageState.OperationWaiting));
}
}
public void Dispose()
{
OperationExecutionState.OnOperationStarted -= OnOperationStarted;
}
}

View File

@ -1,3 +1,4 @@
using Hcs.WebApp.BackgroundServices;
using Hcs.WebApp.Components;
using Hcs.WebApp.Components.Shared;
using Hcs.WebApp.Data.Hcs;
@ -60,6 +61,9 @@ builder.Services.AddScoped<UsersService>();
builder.Services.AddScoped<OperationService>();
builder.Services.AddScoped<RegistryService>();
builder.Services.AddSingleton<OperationExecutionState>();
builder.Services.AddHostedService<OperationExecutionService>();
var activator = new RadzenComponentActivator();
activator.Override(typeof(RadzenDataGrid<>), typeof(LocalizedRadzenDataGrid<>));
builder.Services.AddSingleton<IComponentActivator>(activator);

View File

@ -12,5 +12,19 @@ namespace Hcs.WebApp.Services
using var context = factory.CreateDbContext();
return await context.Operations.AnyAsync(x => x.Type == type && !x.EndedAt.HasValue);
}
public async Task<Operation> InitiateOperation(Operation.OperationType type, string initiatorId)
{
using var context = factory.CreateDbContext();
var operation = new Operation()
{
Type = type,
InitiatorId = initiatorId,
StartedAt = DateTime.UtcNow
};
await context.Operations.AddAsync(operation);
await context.SaveChangesAsync();
return operation;
}
}
}