< Summary

Information
Class: Services.SearchServices.OrderSearch.OrderSearchDiagnosticsStore
Assembly: Services
File(s): /home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SearchServices/OrderSearch/OrderSearchDiagnosticsStore.cs
Line coverage
97%
Covered lines: 44
Uncovered lines: 1
Coverable lines: 45
Total lines: 92
Line coverage: 97.7%
Branch coverage
66%
Covered branches: 4
Total branches: 6
Branch coverage: 66.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%
RecordIndex(...)100%11100%
RecordSearch(...)100%11100%
RecordDrift(...)100%11100%
GetDriftEvents(...)100%11100%
GetLastDriftEvent()100%11100%
GetIndexEvents(...)100%11100%
GetSearchEvents(...)100%11100%
GetSearchStats()100%22100%
Trim(...)50%4475%

File(s)

/home/runner/work/Studio2Prod/Studio2Prod/AppRepository/SearchServices/OrderSearch/OrderSearchDiagnosticsStore.cs

#LineLine coverage
 1using System.Collections.Concurrent;
 2
 3namespace Services.SearchServices.OrderSearch;
 4
 5/// <summary>In-memory журнал индексации и поисковых запросов (singleton на процесс приложения).</summary>
 6public sealed class OrderSearchDiagnosticsStore : IOrderSearchDiagnosticsStore
 7{
 8    private const int MaxIndexEvents = 400;
 9    private const int MaxSearchEvents = 200;
 10    private const int MaxDriftEvents = 100;
 11
 7412    private readonly ConcurrentQueue<OrderSearchIndexEvent> _indexEvents = new();
 7413    private readonly ConcurrentQueue<OrderSearchQueryEvent> _searchEvents = new();
 7414    private readonly ConcurrentQueue<OrderSearchDriftEvent> _driftEvents = new();
 15    private int _indexCount;
 16    private int _searchCount;
 17    private int _driftCount;
 18
 19    public void RecordIndex(OrderSearchIndexOperation operation, int count, long durationMs, bool success,
 20        string message, int? orderId = null)
 21    {
 422        _indexEvents.Enqueue(new OrderSearchIndexEvent
 423        {
 424            Operation = operation,
 425            OrderId = orderId,
 426            Count = count,
 427            DurationMs = durationMs,
 428            Success = success,
 429            Message = message
 430        });
 431        Trim(_indexEvents, ref _indexCount, MaxIndexEvents);
 432    }
 33
 34    public void RecordSearch(string? searchText, string filterSummary, long durationMs, int resultCount,
 35        bool usedFallback, string source = "Orders", long? totalHits = null, bool truncated = false,
 36        bool isLargeResult = false)
 37    {
 1938        _searchEvents.Enqueue(new OrderSearchQueryEvent
 1939        {
 1940            SearchText = searchText,
 1941            FilterSummary = filterSummary,
 1942            DurationMs = durationMs,
 1943            ResultCount = resultCount,
 1944            TotalHits = totalHits,
 1945            Truncated = truncated,
 1946            IsLargeResult = isLargeResult,
 1947            UsedFallback = usedFallback,
 1948            Source = source
 1949        });
 1950        Trim(_searchEvents, ref _searchCount, MaxSearchEvents);
 1951    }
 52
 53    public void RecordDrift(OrderSearchDriftEvent driftEvent)
 54    {
 955        _driftEvents.Enqueue(driftEvent);
 956        Trim(_driftEvents, ref _driftCount, MaxDriftEvents);
 957    }
 58
 59    public IReadOnlyList<OrderSearchDriftEvent> GetDriftEvents(int take = 30) =>
 1160        _driftEvents.Reverse().Take(take).ToList();
 61
 62    public OrderSearchDriftEvent? GetLastDriftEvent() =>
 1163        _driftEvents.Reverse().FirstOrDefault();
 64
 65    public IReadOnlyList<OrderSearchIndexEvent> GetIndexEvents(int take = 80) =>
 1066        _indexEvents.Reverse().Take(take).ToList();
 67
 68    public IReadOnlyList<OrderSearchQueryEvent> GetSearchEvents(int take = 50) =>
 1469        _searchEvents.Reverse().Take(take).ToList();
 70
 71    public (double AvgMs, long MaxMs, int Count) GetSearchStats()
 72    {
 1173        var items = _searchEvents.ToArray();
 1174        if (items.Length == 0)
 75        {
 876            return (0, 0, 0);
 77        }
 78
 979        var avg = items.Average(e => e.DurationMs);
 980        var max = items.Max(e => e.DurationMs);
 381        return (avg, max, items.Length);
 82    }
 83
 84    private static void Trim<T>(ConcurrentQueue<T> queue, ref int counter, int max)
 85    {
 3286        var n = Interlocked.Increment(ref counter);
 3287        while (n > max && queue.TryDequeue(out _))
 88        {
 089            n = Interlocked.Decrement(ref counter);
 90        }
 3291    }
 92}