79 lines
2.9 KiB
C#
79 lines
2.9 KiB
C#
using Microsoft.EntityFrameworkCore;
|
|
using Microsoft.Extensions.Logging;
|
|
using PARR.Common.Domain;
|
|
using PARR.DAL.Models;
|
|
using PARR.DAL.Services.Interfaces;
|
|
using PARR.TemplateMatcher.Services.Interfaces;
|
|
|
|
namespace PARR.TemplateMatcher.Services.Implementations;
|
|
|
|
internal class TemplateReuser : ITemplateReuser
|
|
{
|
|
private readonly ILogger<TemplateReuser> logger;
|
|
private readonly ITemplateService templateService;
|
|
|
|
public TemplateReuser(
|
|
ILogger<TemplateReuser> logger,
|
|
ITemplateService templateService)
|
|
{
|
|
this.logger = logger;
|
|
this.templateService = templateService;
|
|
}
|
|
|
|
public async Task<Template?> TryReuseOneUnusedTemplateAsync(
|
|
Guid jobId,
|
|
Guid unitId,
|
|
HistoryInitiator initiator,
|
|
int maxAttempts = 3)
|
|
{
|
|
for (int attempt = 1; attempt <= maxAttempts; attempt++)
|
|
{
|
|
try
|
|
{
|
|
// Атомарно резервируем один шаблон через DAL
|
|
var templateId = await templateService.ReserveUnusedTemplateAsync(unitId, jobId, initiator);
|
|
|
|
if (templateId == null)
|
|
{
|
|
logger.LogDebug("Нет доступных Unused-шаблонов для переиспользования (попытка {Attempt}).", attempt);
|
|
return null;
|
|
}
|
|
|
|
// Загружаем зарезервированный шаблон
|
|
var template = await templateService.Get()
|
|
.AsNoTracking()
|
|
.Include(t=>t.Unit)
|
|
.Include(t=>t.Job)
|
|
.ThenInclude(t=>t!.Tnk)
|
|
.Include(t => t.Job)
|
|
.ThenInclude(t => t!.Group)
|
|
.ThenInclude(t=>t!.GroupType)
|
|
.FirstOrDefaultAsync(t => t.Id == templateId);
|
|
|
|
if (template == null)
|
|
{
|
|
logger.LogWarning("Зарезервированный шаблон {TemplateId} не найден при загрузке.", templateId);
|
|
continue;
|
|
}
|
|
|
|
logger.LogInformation(
|
|
"Успешно захвачен шаблон {TemplateId} (старый Job {OldJobId}) для нового Job {NewJobId}, Unit {UnitId} (попытка {Attempt}).",
|
|
template.Id, template.JobId, jobId, unitId, attempt);
|
|
|
|
return template;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.LogError(ex, "Ошибка при попытке захвата шаблона (попытка {Attempt}).", attempt);
|
|
|
|
if (attempt == maxAttempts)
|
|
throw;
|
|
|
|
// Небольшая задержка перед повтором
|
|
await Task.Delay(Random.Shared.Next(10, 50));
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
} |