< Summary

Information
Class: OzonOrdersWeb.WebServices.Orders.OrdersStatusSyncHealthStore
Assembly: OzonOrdersWeb
File(s): /home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Orders/OrdersStatusSyncHealthStore.cs
Line coverage
94%
Covered lines: 16
Uncovered lines: 1
Coverable lines: 17
Total lines: 56
Line coverage: 94.1%
Branch coverage
91%
Covered branches: 11
Total branches: 12
Branch coverage: 91.6%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%11100%
get_HasProblem()100%11100%
get_Details()100%11100%
get_LastRunUtc()100%210%
Record(...)91.66%1212100%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/OzonOrdersWeb/WebServices/Orders/OrdersStatusSyncHealthStore.cs

#LineLine coverage
 1namespace OzonOrdersWeb.WebServices.Orders;
 2
 3/// <summary>
 4/// Здоровье фонового опроса статусов Ozon (<see cref="OrdersClientStatusReconcileJob"/>) в памяти процесса.
 5/// Если опрос подряд не получает ответов от Ozon (протух API-ключ, 403/429, недоступен API),
 6/// статусы молча перестают обновляться — админу нужен баннер и Telegram.
 7/// </summary>
 8public sealed class OrdersStatusSyncHealthStore
 9{
 10    /// <summary>Доля неудачных запросов в пачке, начиная с которой запуск считается сбойным.</summary>
 11    public const double FailureRatioThreshold = 0.5;
 12
 13    /// <summary>Сколько сбойных запусков подряд считаем проблемой (один — случайный всплеск).</summary>
 14    public const int ConsecutiveFailuresThreshold = 2;
 15
 216    private readonly object _gate = new();
 17    private int _consecutiveFailures;
 18    private string? _lastDetails;
 19    private DateTime? _lastRunUtc;
 20    private bool _alerted;
 21
 22    public bool HasProblem
 23    {
 1224        get { lock (_gate) return _consecutiveFailures >= ConsecutiveFailuresThreshold; }
 25    }
 26
 27    public string? Details
 28    {
 329        get { lock (_gate) return _lastDetails; }
 30    }
 31
 32    public DateTime? LastRunUtc
 33    {
 034        get { lock (_gate) return _lastRunUtc; }
 35    }
 36
 37    /// <summary>Учитывает итог запуска. Возвращает true, если состояние (проблема есть/нет) изменилось и нужен алерт.</
 38    public bool Record(int total, int failed, string? error, out bool nowProblem)
 39    {
 740        lock (_gate)
 41        {
 742            _lastRunUtc = DateTime.UtcNow;
 743            var failedRun = error != null || (total > 0 && (double)failed / total >= FailureRatioThreshold);
 744            _consecutiveFailures = failedRun ? _consecutiveFailures + 1 : 0;
 745            _lastDetails = failedRun
 746                ? error ?? $"Ozon не ответил по {failed} из {total} заказов в последней пачке"
 747                : null;
 48
 749            nowProblem = _consecutiveFailures >= ConsecutiveFailuresThreshold;
 750            if (nowProblem == _alerted)
 551                return false;
 252            _alerted = nowProblem;
 253            return true;
 54        }
 755    }
 56}