< Summary

Information
Class: TeleFlow.Telegram.Internal.TelegramHandlerRequestTimingScope
Assembly: TeleFlow.Telegram.Client
File(s): /_/src/TeleFlow.Telegram.Client/Internal/TelegramHandlerRequestTimingScope.cs
Line coverage
86%
Covered lines: 39
Uncovered lines: 6
Coverable lines: 45
Total lines: 111
Line coverage: 86.6%
Branch coverage
56%
Covered branches: 9
Total branches: 16
Branch coverage: 56.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.cctor()100%11100%
.ctor(...)100%11100%
Begin()100%11100%
get_HasCurrent()100%11100%
Record(...)50%4475%
CreateSummary(...)50%2288.88%
Dispose()50%2280%
CalculateMergedRequestWait(...)62.5%8884.21%

File(s)

/_/src/TeleFlow.Telegram.Client/Internal/TelegramHandlerRequestTimingScope.cs

#LineLine coverage
 1using System.Threading;
 2
 3namespace TeleFlow.Telegram.Internal;
 4
 5internal sealed class TelegramHandlerRequestTimingScope : IDisposable
 6{
 17    private static readonly AsyncLocal<TelegramHandlerRequestTimingScope?> CurrentSlot = new();
 8
 9    private readonly TelegramHandlerRequestTimingScope? _previous;
 1010    private readonly List<RequestInterval> _intervals = [];
 11    private bool _disposed;
 12
 13    private TelegramHandlerRequestTimingScope(TelegramHandlerRequestTimingScope? previous)
 14    {
 1015        _previous = previous;
 1016    }
 17
 18    public static TelegramHandlerRequestTimingScope Begin()
 19    {
 1020        var scope = new TelegramHandlerRequestTimingScope(CurrentSlot.Value);
 1021        CurrentSlot.Value = scope;
 1022        return scope;
 23    }
 24
 8325    public static bool HasCurrent => CurrentSlot.Value is not null;
 26
 27    public static void Record(long startTimestamp, long endTimestamp)
 28    {
 429        if (endTimestamp < startTimestamp)
 30        {
 031            return;
 32        }
 33
 434        CurrentSlot.Value?._intervals.Add(new RequestInterval(startTimestamp, endTimestamp));
 435    }
 36
 37    public TelegramHandlerRequestTimingSummary CreateSummary(
 38        TimeProvider timeProvider,
 39        TimeSpan handlerElapsed)
 40    {
 1041        ArgumentNullException.ThrowIfNull(timeProvider);
 42
 1043        var requestWait = CalculateMergedRequestWait(timeProvider);
 1044        var logic = handlerElapsed - requestWait;
 45
 1046        if (logic < TimeSpan.Zero)
 47        {
 048            logic = TimeSpan.Zero;
 49        }
 50
 1051        return new TelegramHandlerRequestTimingSummary(
 1052            _intervals.Count,
 1053            requestWait.TotalMilliseconds,
 1054            logic.TotalMilliseconds);
 55    }
 56
 57    public void Dispose()
 58    {
 1059        if (_disposed)
 60        {
 061            return;
 62        }
 63
 1064        _disposed = true;
 1065        CurrentSlot.Value = _previous;
 1066    }
 67
 68    private TimeSpan CalculateMergedRequestWait(TimeProvider timeProvider)
 69    {
 1070        if (_intervals.Count == 0)
 71        {
 772            return TimeSpan.Zero;
 73        }
 74
 375        var ordered = _intervals
 276            .OrderBy(static interval => interval.StartTimestamp)
 377            .ToArray();
 378        var currentStart = ordered[0].StartTimestamp;
 379        var currentEnd = ordered[0].EndTimestamp;
 380        var total = TimeSpan.Zero;
 81
 882        for (var index = 1; index < ordered.Length; index++)
 83        {
 184            var interval = ordered[index];
 85
 186            if (interval.StartTimestamp <= currentEnd)
 87            {
 088                if (interval.EndTimestamp > currentEnd)
 89                {
 090                    currentEnd = interval.EndTimestamp;
 91                }
 92
 093                continue;
 94            }
 95
 196            total += timeProvider.GetElapsedTime(currentStart, currentEnd);
 197            currentStart = interval.StartTimestamp;
 198            currentEnd = interval.EndTimestamp;
 99        }
 100
 3101        total += timeProvider.GetElapsedTime(currentStart, currentEnd);
 3102        return total;
 103    }
 104
 105    private readonly record struct RequestInterval(long StartTimestamp, long EndTimestamp);
 106}
 107
 108internal readonly record struct TelegramHandlerRequestTimingSummary(
 109    int RequestCount,
 110    double RequestElapsedMilliseconds,
 111    double HandlerLogicElapsedMilliseconds);