< Summary

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

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%210%
.cctor()100%210%
EvaluateAsync()0%2040%
HandleOzonCancelledAsync()100%210%
SyncPinnedAsync()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>
 010public sealed class SystemAlertEvaluationService(SystemAlertFactory factory, SystemAlertTelegramNotifier telegram,
 011    SystemAlertPinnedMessageService pinned, OzonCancelledSupplierOrderHandler ozonCancelled, ILogger<SystemAlertEvaluati
 12{
 013    private static readonly SemaphoreSlim Gate = new(1, 1);
 014    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    {
 019        await Gate.WaitAsync(cancellationToken);
 20        try
 21        {
 022            if (DateTime.UtcNow - _lastEvaluatedAtUtc < minInterval) return false;
 023            var transitions = await factory.EvaluateAsync(cancellationToken);
 024            _lastEvaluatedAtUtc = DateTime.UtcNow;
 025            await telegram.NotifyAsync(transitions, cancellationToken);
 026            await HandleOzonCancelledAsync(cancellationToken);
 027            await SyncPinnedAsync(cancellationToken);
 028            return true;
 29        }
 30        finally
 31        {
 032            Gate.Release();
 33        }
 034    }
 35
 36    /// <summary>Автоотмена у поставщика заказов, отменённых в Ozon, и сообщение в General; сбой не мешает алертам.</sum
 37    private async Task HandleOzonCancelledAsync(CancellationToken cancellationToken)
 38    {
 39        try
 40        {
 041            await ozonCancelled.HandleAsync(cancellationToken);
 042        }
 043        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 44        {
 045            throw;
 46        }
 047        catch (Exception ex)
 48        {
 049            logger.LogWarning(ex, "Не удалось обработать заказы, отменённые в Ozon при живом заказе у поставщика");
 050        }
 051    }
 52
 53    private async Task SyncPinnedAsync(CancellationToken cancellationToken)
 54    {
 55        try
 56        {
 057            var active = await factory.GetAlertsAsync(cancellationToken);
 058            await pinned.SyncAsync(SystemAlertTelegramNotifier.ToItems(active), cancellationToken);
 059        }
 060        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
 61        {
 062            throw;
 63        }
 064        catch (Exception ex)
 65        {
 066            logger.LogWarning(ex, "Не удалось обновить закреплённое сообщение алертов в Telegram");
 067        }
 068    }
 69}
 70
 71public 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)]
 79    public async Task ExecuteAsync() => await evaluation.EvaluateAsync(TimeSpan.Zero);
 80}