feat(api, Core, TaskReconciliationWorker): Воркер обработки зависших задач. Доработка логики.
This commit is contained in:
@@ -89,6 +89,10 @@ namespace PARR.Core.Services.Task.Implementations
|
||||
// Не пробрасываем исключение дальше — задача создана, просто не в очереди.
|
||||
// задача останется в БД со статусом pending, и Reconciliation Task позже ее возмет в работу
|
||||
logger.LogError("Не удалось опубликовать задачу {TaskId} в очередь. Задача осталась в БД со статусом Pending.", task.Id);
|
||||
|
||||
// так как задачу не смогли отправить в очередь повторно, обновим ей DateModified, относительно нее считается время обработки, и задача встанет на повтор позже сама
|
||||
task.DateModified = DateTimeOffset.UtcNow;
|
||||
await taskRepository.CommitAsync();
|
||||
}
|
||||
|
||||
return task.Id;
|
||||
|
||||
@@ -98,12 +98,15 @@ namespace PARR.Core.Services.Task.Implementations
|
||||
|
||||
return await taskRepository.Get()
|
||||
.Where(t =>
|
||||
t.TypeCode == taskType.Code && t.DateModified < timeoutThreshold &&
|
||||
(
|
||||
//t.TypeCode == taskType.Code && t.DateModified < timeoutThreshold &&
|
||||
t.TypeCode == taskType.Code
|
||||
// если это вновь созданная задача и она упала, то у нее может не быть DateModified, тогда сравним с DateCreated
|
||||
&& (t.DateModified ?? t.DateCreated) < timeoutThreshold
|
||||
&& (
|
||||
// Зависла в Processing
|
||||
t.StatusCode == TaskItemStatusEnum.Processing
|
||||
//Зависли в Pending
|
||||
|| (t.StatusCode == TaskItemStatusEnum.Pending && t.RetryCount > 0)
|
||||
|| (t.StatusCode == TaskItemStatusEnum.Pending /*&& t.RetryCount > 0*/)
|
||||
)
|
||||
)
|
||||
.OrderBy(t => t.DateModified) // Сначала самые старые
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Common.Interfaces;
|
||||
using PARR.Core.Services.Task.Interfaces;
|
||||
using PARR.Domain.Settings;
|
||||
|
||||
namespace PARR.Core.Services.Task.ReconciliationHosted
|
||||
{
|
||||
/// <summary>
|
||||
/// Фоновая задача для периодического запуска Reconciliation Job.
|
||||
/// Обработка зависших задач.
|
||||
/// </summary>
|
||||
internal class ReconciliationHostedService : BackgroundService
|
||||
{
|
||||
// Это реализация воркера, подключается напрямую в воркер
|
||||
|
||||
private readonly ILogger<ReconciliationHostedService> logger;
|
||||
private readonly IReconciliationSettings reconciliationSettings;
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IIntervalService intervalService;
|
||||
|
||||
public ReconciliationHostedService(
|
||||
ILogger<ReconciliationHostedService> logger,
|
||||
IReconciliationSettings reconciliationSettings,
|
||||
IServiceProvider serviceProvider,
|
||||
IIntervalService intervalService
|
||||
)
|
||||
{
|
||||
this.logger = logger;
|
||||
this.reconciliationSettings = reconciliationSettings;
|
||||
this.serviceProvider = serviceProvider;
|
||||
this.intervalService = intervalService;
|
||||
}
|
||||
|
||||
protected override async System.Threading.Tasks.Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
await intervalService.IntervalInitAsync(async () =>
|
||||
{
|
||||
await using (var scope = serviceProvider.CreateAsyncScope())
|
||||
{
|
||||
var reconciliationService = scope.ServiceProvider.GetRequiredService<ITaskReconciliationService>();
|
||||
|
||||
// Запускаем проверку
|
||||
var report = await reconciliationService.RunAsync();
|
||||
|
||||
if (report.HasChanged)
|
||||
logger.LogInformation("Reconciliation Job выполнен. Проверено: {Checked}, Исправлено: {Fixed}", report.CheckedCount, report.FixedCount);
|
||||
}
|
||||
|
||||
}, reconciliationSettings.CheckInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using PARR.Core.Common.Interfaces;
|
||||
using PARR.Core.Common.Interfaces.RabbitServices;
|
||||
using PARR.Core.Services.Task.Handlers;
|
||||
using PARR.Core.Services.Task.Handlers.Factory;
|
||||
using PARR.Core.Services.Workload.Interfaces;
|
||||
using PARR.Domain.Common.Rabbit.Messages;
|
||||
|
||||
Reference in New Issue
Block a user