< Summary

Information
Class: OzonOrdersWeb.WebServices.SystemAlerts.SystemAlertEvaluationJob
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/SystemAlerts/SystemAlertEvaluationJob.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 2
Coverable lines: 2
Total lines: 80
Line coverage: 0%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
ExecuteAsync()100%210%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/SystemAlerts/SystemAlertEvaluationJob.cs

#LineLine coverage
 1using Hangfire;
 2using Services.HangfireService;
 3
 4namespace OzonOrdersWeb.WebServices.SystemAlerts;
 5
 6/// <summary>
 7/// Пересчёт системных алертов с отправкой изменений в Telegram и обновлением закреплённого сообщения. Вызывается джобом
 8/// проверки сериализуются, чтобы одновременный запуск не создал дубликаты инцидентов.
 9/// </summary>
 10public sealed class SystemAlertEvaluationService(SystemAlertFactory factory, SystemAlertTelegramNotifier telegram,
 11    SystemAlertPinnedMessageService pinned, OzonCancelledSupplierOrderHandler ozonCancelled, ILogger<SystemAlertEvaluati
 12{
 13    private static readonly SemaphoreSlim Gate = new(1, 1);
 14    private static DateTime _lastEvaluatedAtUtc = DateTime.MinValue;
 15
 16    /// <summary>Возвращает false, если проверка не выполнялась: предыдущая была менее <paramref name="minInterval"/> на
 17    public async Task<bool> EvaluateAsync(TimeSpan minInterval, CancellationToken cancellationToken = default)
 18    {
 19        await Gate.WaitAsync(cancellationToken);
 20        try
 21        {
 22            if (DateTime.UtcNow - _lastEvaluatedAtUtc < minInterval) return false;
 23            var transitions = await factory.EvaluateAsync(cancellationToken);
 24            _lastEvaluatedAtUtc = DateTime.UtcNow;
 25            await telegram.NotifyAsync(transitions, cancellationToken);
 26            await HandleOzonCancelledAsync(cancellationToken);
 27            await SyncPinnedAsync(cancellationToken);
 28            return true;
 29        }
 30        finally
 31        {
 32            Gate.Release();
 33        }
 34    }
 35
 36    /// <summary>Автоотмена у поставщика заказов, отменённых в Ozon, и сообщение в General; сбой не мешает алертам.</sum
 37    private async Task HandleOzonCancelledAsync(CancellationToken cancellationToken)
 38    {
 39        try
 40        {
 41            await ozonCancelled.HandleAsync(cancellationToken);
 42        }
 43        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 44        {
 45            throw;
 46        }
 47        catch (Exception ex)
 48        {
 49            logger.LogWarning(ex, "Не удалось обработать заказы, отменённые в Ozon при живом заказе у поставщика");
 50        }
 51    }
 52
 53    private async Task SyncPinnedAsync(CancellationToken cancellationToken)
 54    {
 55        try
 56        {
 57            var active = await factory.GetAlertsAsync(cancellationToken);
 58            await pinned.SyncAsync(SystemAlertTelegramNotifier.ToItems(active), cancellationToken);
 59        }
 60        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 61        {
 62            throw;
 63        }
 64        catch (Exception ex)
 65        {
 66            logger.LogWarning(ex, "Не удалось обновить закреплённое сообщение алертов в Telegram");
 67        }
 68    }
 69}
 70
 071public sealed class SystemAlertEvaluationJob(SystemAlertEvaluationService evaluation)
 72{
 73    public const string JobId = "system-alert-evaluation";
 74    public const string DefaultCron = "*/5 * * * *";
 75
 76    [Queue(HangfireQueueNames.Main)]
 77    [DisableConcurrentExecution(0)]
 78    [AutomaticRetry(Attempts = 0)]
 079    public async Task ExecuteAsync() => await evaluation.EvaluateAsync(TimeSpan.Zero);
 80}