Files
InServiceQue/InServiceQue/Services/QueueService.cs

108 lines
3.2 KiB
C#

using System.Diagnostics;
using InServiceQue.Core.Models;
using InServiceQue.Core.Repositories;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace InServiceQue.Services;
public class QueueService<T> : BackgroundService, IQueueService<T>
where T: IQueueTask
{
private readonly ITaskRepository _repository;
private readonly IServiceProvider _serviceProvider;
public QueueService(ITaskRepository repository, IServiceProvider serviceProvider)
{
_repository = repository;
_serviceProvider = serviceProvider;
}
public void TryProcessTask()
{
using (var scope = _serviceProvider.CreateScope())
{
using var tx = _repository.StartTransaction();
var queueTask = _repository.GetNextTask(tx, typeof(T).Name);
if (queueTask == null)
{
_repository.RollbackTransaction(tx);
return;
}
var serviceHandler = scope.ServiceProvider.GetService(typeof(IQueueHandler<>).MakeGenericType(typeof(T)));
var handler = (IQueueHandler)serviceHandler;
try
{
Handle(queueTask, handler);
_repository.SaveTask(queueTask, tx);
_repository.CommitTransaction(tx);
}
catch (Exception e)
{
// ignored
}
}
}
public async Task TryProcessTaskAsync()
{
using (var scope = _serviceProvider.CreateScope())
{
using var tx = await _repository.StartTransactionAsync();
var taskType = typeof(T);
var queueTask = await _repository.GetNextTaskAsync(tx, taskType.Name);
if (queueTask == null)
{
await _repository.RollbackTransactionAsync(tx);
return;
}
var serviceHandler = scope.ServiceProvider.GetService(typeof(IQueueHandler<>).MakeGenericType(taskType));
var handler = (IQueueHandler)serviceHandler;
try
{
await HandleAsync(queueTask, handler);
await _repository.SaveTaskAsync(queueTask, tx);
await _repository.CommitTransactionAsync(tx);
}
catch (Exception e)
{
// ignored
}
}
}
internal void Handle(QueueTask queueTask, IQueueHandler handler)
{
queueTask.MarkAttempt();
var success = handler.Handle(queueTask.Payload ?? string.Empty);
if (success)
{
queueTask.SolveTask();
}
}
internal async Task HandleAsync(QueueTask queueTask, IQueueHandler handler)
{
queueTask.MarkAttempt();
var success = await handler.HandleAsync(queueTask.Payload ?? string.Empty);
if (success)
{
queueTask.SolveTask();
}
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (true)
{
await TryProcessTaskAsync();
await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
}
}
}