Files
hcs/Hcs.WebApp/BackgroundServices/DataParsingService.cs

77 lines
3.0 KiB
C#

using Hcs.WebApp.BackgroundServices.DataParsers;
using Hcs.WebApp.Services;
using Hcs.WebApp.Utils;
namespace Hcs.WebApp.BackgroundServices
{
public class DataParsingService(
DataParsingState state,
DataParserFactory dataParserFactory,
IServiceScopeFactory scopeFactory,
IWebHostEnvironment webHostEnvironment) : BackgroundService
{
private const int SLEEP_TIME = 30000;
private readonly DataParsingState state = state;
private readonly DataParserFactory dataParserFactory = dataParserFactory;
private readonly IServiceScopeFactory scopeFactory = scopeFactory;
private readonly IWebHostEnvironment webHostEnvironment = webHostEnvironment;
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
await InitializeStateAsync();
while (!stoppingToken.IsCancellationRequested)
{
while (state.TryDequeueOperation(out var operation))
{
state.SetProcessingOperation(operation);
if (stoppingToken.IsCancellationRequested) return;
var scope = scopeFactory.CreateScope();
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
try
{
var startedAt = DateTime.Now;
await headquartersService.SetOperationStartedAsync(operation.Id, startedAt);
state.InvokeOnOperationStarted(operation.Id, operation.CampaignId, startedAt);
var dataParser = dataParserFactory.CreateDataParser(scope, operation, webHostEnvironment);
await dataParser.ParseAsync();
state.InvokeOnOperationEnded(operation.Id, operation.CampaignId, DateTime.Now, string.Empty);
}
catch (Exception e)
{
var failedAt = DateTime.Now;
var failureReason = e.CombineMessages();
await headquartersService.SetOperationEndedWithFailAsync(operation.Id, failedAt, failureReason);
state.InvokeOnOperationEnded(operation.Id, operation.CampaignId, failedAt, failureReason);
}
state.UnsetProcessingOperation(operation);
}
await Task.Delay(SLEEP_TIME, stoppingToken);
}
}
private async Task InitializeStateAsync()
{
using var scope = scopeFactory.CreateScope();
var headquartersService = scope.ServiceProvider.GetRequiredService<HeadquartersService>();
var operations = await headquartersService.GetNotCompletedParseOperationsAsync();
foreach (var operation in operations)
{
state.EnqueueOperation(operation);
}
state.Ready = true;
}
}
}