Complete campaign flow
This commit is contained in:
@ -30,17 +30,22 @@ namespace Hcs.WebApp.BackgroundServices
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var manager = managerFactory.CreateManager(scope, campaign);
|
var manager = managerFactory.CreateManager(scope, campaign);
|
||||||
await manager.StartAsync(stoppingToken);
|
await manager.StartAsync();
|
||||||
|
|
||||||
managers.Add(manager);
|
managers.Add(manager);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
|
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
|
||||||
await headquartersService.SetCampaignEndedWithFail(campaign.Id, e.Message);
|
await headquartersService.SetCampaignEndedWithFailAsync(campaign.Id, e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreach (var manager in managers)
|
||||||
|
{
|
||||||
|
await manager.CheckStateAsync();
|
||||||
|
}
|
||||||
|
|
||||||
managers.RemoveAll(x => x.State == IManager.ManagerState.Ended);
|
managers.RemoveAll(x => x.State == IManager.ManagerState.Ended);
|
||||||
|
|
||||||
if (managers.Count > 0)
|
if (managers.Count > 0)
|
||||||
|
|||||||
@ -3,22 +3,57 @@ using Hcs.WebApp.Services;
|
|||||||
|
|
||||||
namespace Hcs.WebApp.BackgroundServices.CampaignManagers
|
namespace Hcs.WebApp.BackgroundServices.CampaignManagers
|
||||||
{
|
{
|
||||||
public class ExportRequiredRegistryElementsManager_15_7_0_1(IServiceScope scope, OperationExecutionState state, Campaign campaign) : ManagerBase(scope, state, campaign)
|
public class ExportRequiredRegistryElementsManager_15_7_0_1(IServiceScope scope, OperationExecutionState operationExecutionState, Campaign campaign) : ManagerBase(scope, operationExecutionState, campaign)
|
||||||
{
|
{
|
||||||
public override async Task StartAsync(CancellationToken cancellationToken)
|
public override async Task StartAsync()
|
||||||
{
|
{
|
||||||
|
if (campaign.Step > 0) return;
|
||||||
|
|
||||||
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
|
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
|
||||||
var registryService = scope.ServiceProvider.GetRequiredService<RegistryService>();
|
var registryService = scope.ServiceProvider.GetRequiredService<RegistryService>();
|
||||||
using var context = headquartersService.GetNewContext();
|
using var context = headquartersService.GetNewContext();
|
||||||
using var transaction = await context.Database.BeginTransactionAsync(cancellationToken);
|
using var transaction = await context.Database.BeginTransactionAsync();
|
||||||
|
IEnumerable<Operation> operations = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// TODO
|
await headquartersService.SetCampaignStartedAsync(context, campaign.Id);
|
||||||
|
await headquartersService.SetCampaignStepAsync(context, campaign.Id, 1);
|
||||||
|
var registryCount = await registryService.GetRegistryCountAsync(context);
|
||||||
|
operations = await headquartersService.InitiateOperationsAsync(context, registryCount, campaign.Id, Operation.OperationType.NsiCommon_ExportNsiItem_15_7_0_1);
|
||||||
|
await registryService.SetOperationsToRegistriesAsync(context, operations);
|
||||||
|
await transaction.CommitAsync();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
transaction?.Rollback();
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (operations != null)
|
||||||
|
{
|
||||||
|
foreach (var operation in operations)
|
||||||
|
{
|
||||||
|
operationExecutionState.EnqueueOperation(operation);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
State = IManager.ManagerState.Started;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async Task CheckStateAsync()
|
||||||
|
{
|
||||||
|
if (State == IManager.ManagerState.Started)
|
||||||
|
{
|
||||||
|
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
|
||||||
|
var hasActiveOperations = await headquartersService.HasActiveOperationsAsync(campaign.Id);
|
||||||
|
if (!hasActiveOperations)
|
||||||
|
{
|
||||||
|
State = IManager.ManagerState.Ended;
|
||||||
|
|
||||||
|
await headquartersService.SetCampaignEndedAsync(campaign.Id);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,12 +6,13 @@
|
|||||||
{
|
{
|
||||||
Created,
|
Created,
|
||||||
Started,
|
Started,
|
||||||
Working,
|
|
||||||
Ended
|
Ended
|
||||||
}
|
}
|
||||||
|
|
||||||
public ManagerState State { get; }
|
public ManagerState State { get; }
|
||||||
|
|
||||||
Task StartAsync(CancellationToken cancellationToken);
|
Task StartAsync();
|
||||||
|
|
||||||
|
Task CheckStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,14 +2,16 @@
|
|||||||
|
|
||||||
namespace Hcs.WebApp.BackgroundServices.CampaignManagers
|
namespace Hcs.WebApp.BackgroundServices.CampaignManagers
|
||||||
{
|
{
|
||||||
public abstract class ManagerBase(IServiceScope scope, OperationExecutionState state, Campaign campaign) : IManager
|
public abstract class ManagerBase(IServiceScope scope, OperationExecutionState operationExecutionState, Campaign campaign) : IManager
|
||||||
{
|
{
|
||||||
protected readonly IServiceScope scope = scope;
|
protected readonly IServiceScope scope = scope;
|
||||||
protected readonly OperationExecutionState state = state;
|
protected readonly OperationExecutionState operationExecutionState = operationExecutionState;
|
||||||
protected readonly Campaign campaign = campaign;
|
protected readonly Campaign campaign = campaign;
|
||||||
|
|
||||||
public IManager.ManagerState State { get; } = IManager.ManagerState.Created;
|
public IManager.ManagerState State { get; protected set; } = IManager.ManagerState.Created;
|
||||||
|
|
||||||
public abstract Task StartAsync(CancellationToken cancellationToken);
|
public abstract Task StartAsync();
|
||||||
|
|
||||||
|
public abstract Task CheckStateAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,12 +37,12 @@ namespace Hcs.WebApp.BackgroundServices
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var executor = executorFactory.CreateExecutor(scope, client, operation);
|
var executor = executorFactory.CreateExecutor(scope, client, operation);
|
||||||
await headquartersService.SetOperationStarted(operation.Id);
|
await headquartersService.SetOperationStartedAsync(operation.Id);
|
||||||
messageGuid = await executor.ExecuteAsync(stoppingToken);
|
messageGuid = await executor.ExecuteAsync(stoppingToken);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
await headquartersService.SetOperationEndedWithFail(operation.Id, e.Message);
|
await headquartersService.SetOperationEndedWithFailAsync(operation.Id, e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(messageGuid))
|
if (!string.IsNullOrEmpty(messageGuid))
|
||||||
|
|||||||
@ -11,6 +11,12 @@ namespace Hcs.WebApp.Services
|
|||||||
return await context.Campaigns.AnyAsync(x => x.Type == type && !x.EndedAt.HasValue);
|
return await context.Campaigns.AnyAsync(x => x.Type == type && !x.EndedAt.HasValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<bool> HasActiveOperationsAsync(int campaignId)
|
||||||
|
{
|
||||||
|
using var context = GetNewContext();
|
||||||
|
return await context.Operations.CountAsync(x => x.CampaignId == campaignId && !x.EndedAt.HasValue) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Campaign>> GetInitiatedCampaignAsync()
|
public async Task<IEnumerable<Campaign>> GetInitiatedCampaignAsync()
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
using var context = GetNewContext();
|
||||||
@ -41,21 +47,59 @@ namespace Hcs.WebApp.Services
|
|||||||
return campaign;
|
return campaign;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<Operation> InitiateOperationAsync(int campaignId, Operation.OperationType type)
|
public async Task<IEnumerable<Operation>> InitiateOperationsAsync(HcsDbContext context, int count, int campaignId, Operation.OperationType type)
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
var operations = new List<Operation>();
|
||||||
var operation = new Operation()
|
for (var i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
operations.Add(new Operation()
|
||||||
{
|
{
|
||||||
CampaignId = campaignId,
|
CampaignId = campaignId,
|
||||||
Type = type,
|
Type = type,
|
||||||
CreatedAt = DateTime.UtcNow
|
CreatedAt = DateTime.UtcNow
|
||||||
};
|
});
|
||||||
await context.Operations.AddAsync(operation);
|
}
|
||||||
|
await context.Operations.AddRangeAsync(operations);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
return operation;
|
return operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetCampaignEndedWithFail(int campaignId, string failureReason)
|
public async Task SetCampaignStartedAsync(HcsDbContext context, int campaignId)
|
||||||
|
{
|
||||||
|
var campaign = await context.Campaigns.FirstOrDefaultAsync(x => x.Id == campaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
campaign.StartedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetOperationStartedAsync(int operationId)
|
||||||
|
{
|
||||||
|
using var context = GetNewContext();
|
||||||
|
var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId);
|
||||||
|
if (operation != null)
|
||||||
|
{
|
||||||
|
operation.StartedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetCampaignEndedAsync(int campaignId)
|
||||||
|
{
|
||||||
|
using var context = GetNewContext();
|
||||||
|
var campaign = await context.Campaigns.FirstOrDefaultAsync(x => x.Id == campaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
campaign.EndedAt = DateTime.UtcNow;
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task SetCampaignEndedWithFailAsync(int campaignId, string failureReason)
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
using var context = GetNewContext();
|
||||||
var campaign = await context.Campaigns.FirstOrDefaultAsync(x => x.Id == campaignId);
|
var campaign = await context.Campaigns.FirstOrDefaultAsync(x => x.Id == campaignId);
|
||||||
@ -68,19 +112,7 @@ namespace Hcs.WebApp.Services
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetOperationStarted(int operationId)
|
public async Task SetOperationEndedWithFailAsync(int operationId, string failureReason)
|
||||||
{
|
|
||||||
using var context = GetNewContext();
|
|
||||||
var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId);
|
|
||||||
if (operation != null)
|
|
||||||
{
|
|
||||||
operation.StartedAt = DateTime.UtcNow;
|
|
||||||
|
|
||||||
await context.SaveChangesAsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SetOperationEndedWithFail(int operationId, string failureReason)
|
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
using var context = GetNewContext();
|
||||||
var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId);
|
var operation = await context.Operations.FirstOrDefaultAsync(x => x.Id == operationId);
|
||||||
@ -104,5 +136,16 @@ namespace Hcs.WebApp.Services
|
|||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task SetCampaignStepAsync(HcsDbContext context, int campaignId, int step)
|
||||||
|
{
|
||||||
|
var campaign = await context.Campaigns.FirstOrDefaultAsync(x => x.Id == campaignId);
|
||||||
|
if (campaign != null)
|
||||||
|
{
|
||||||
|
campaign.Step = step;
|
||||||
|
|
||||||
|
await context.SaveChangesAsync();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,6 +5,11 @@ namespace Hcs.WebApp.Services
|
|||||||
{
|
{
|
||||||
public class RegistryService(IDbContextFactory<HcsDbContext> factory) : HcsServiceBase(factory)
|
public class RegistryService(IDbContextFactory<HcsDbContext> factory) : HcsServiceBase(factory)
|
||||||
{
|
{
|
||||||
|
public async Task<int> GetRegistryCountAsync(HcsDbContext context)
|
||||||
|
{
|
||||||
|
return await context.Registries.CountAsync();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Registry>> GetAllRegistriesAsync(bool isCommon)
|
public async Task<IEnumerable<Registry>> GetAllRegistriesAsync(bool isCommon)
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
using var context = GetNewContext();
|
||||||
@ -19,7 +24,7 @@ namespace Hcs.WebApp.Services
|
|||||||
return await context.Registries.SingleAsync(x => x.LastSyncOperationId == operationId);
|
return await context.Registries.SingleAsync(x => x.LastSyncOperationId == operationId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IEnumerable<Registry>> GetRegistriesByOperationId(int operationId)
|
public async Task<IEnumerable<Registry>> GetRegistriesByOperationIdAsync(int operationId)
|
||||||
{
|
{
|
||||||
using var context = GetNewContext();
|
using var context = GetNewContext();
|
||||||
return await (from registry in context.Registries
|
return await (from registry in context.Registries
|
||||||
@ -27,9 +32,10 @@ namespace Hcs.WebApp.Services
|
|||||||
select registry).ToListAsync();
|
select registry).ToListAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetOperationIdToAllRegistries(HcsDbContext context, int operationId)
|
public async Task SetOperationsToRegistriesAsync(HcsDbContext context, IEnumerable<Operation> operations)
|
||||||
{
|
{
|
||||||
await context.Registries.ForEachAsync(x => x.LastSyncOperationId = operationId);
|
var queue = new Queue<Operation>(operations);
|
||||||
|
await context.Registries.ForEachAsync(x => x.LastSyncOperationId = queue.Dequeue().Id);
|
||||||
await context.SaveChangesAsync();
|
await context.SaveChangesAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user