< Summary

Information
Class: TeleFlow.Framework.Middleware.UpdateRateLimitMiddleware
Assembly: TeleFlow.Framework.Core
File(s): /_/src/TeleFlow.Framework.Core/Middleware/UpdateRateLimitMiddleware.cs
Line coverage
100%
Covered lines: 25
Uncovered lines: 0
Coverable lines: 25
Total lines: 74
Line coverage: 100%
Branch coverage
80%
Covered branches: 8
Total branches: 10
Branch coverage: 80%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%
.ctor(...)100%11100%
InvokeAsync()80%1010100%

File(s)

/_/src/TeleFlow.Framework.Core/Middleware/UpdateRateLimitMiddleware.cs

#LineLine coverage
 1using Microsoft.Extensions.Logging;
 2using TeleFlow.Framework.RateLimiting;
 3using TeleFlow.Framework.Updates;
 4
 5namespace TeleFlow.Framework.Middleware;
 6
 7/// <summary>
 8/// Runs registered update-level rate limiters before the dispatcher receives the update.
 9/// </summary>
 10public sealed partial class UpdateRateLimitMiddleware : IUpdateMiddleware
 11{
 12    private const int UpdateRejectedEventId = 1;
 13
 14    private readonly IReadOnlyList<IUpdateRateLimiter> _rateLimiters;
 15    private readonly ILogger<UpdateRateLimitMiddleware>? _logger;
 16
 17    public UpdateRateLimitMiddleware(IEnumerable<IUpdateRateLimiter> rateLimiters)
 18    {
 319        ArgumentNullException.ThrowIfNull(rateLimiters);
 20
 321        _rateLimiters = rateLimiters.ToArray();
 322    }
 23
 24    public UpdateRateLimitMiddleware(
 25        IEnumerable<IUpdateRateLimiter> rateLimiters,
 26        ILogger<UpdateRateLimitMiddleware> logger)
 127        : this(rateLimiters)
 28    {
 129        ArgumentNullException.ThrowIfNull(logger);
 30
 131        _logger = logger;
 132    }
 33
 34    public async Task InvokeAsync(UpdateContext context, UpdateDelegate next)
 35    {
 336        ArgumentNullException.ThrowIfNull(context);
 337        ArgumentNullException.ThrowIfNull(next);
 38
 1339        foreach (var rateLimiter in _rateLimiters)
 40        {
 441            var decision = await rateLimiter
 442                .CheckAsync(context, context.CancellationToken)
 443                .ConfigureAwait(false);
 44
 445            if (!decision.IsAccepted)
 46            {
 147                if (_logger is not null)
 48                {
 149                    LogUpdateRejected(
 150                        _logger,
 151                        context.Payload.GetType().Name,
 152                        rateLimiter.GetType().FullName ?? rateLimiter.GetType().Name,
 153                        decision.RetryAfter,
 154                        decision.PolicyName ?? string.Empty);
 55                }
 56
 157                return;
 58            }
 359        }
 60
 261        await next(context).ConfigureAwait(false);
 362    }
 63
 64    [LoggerMessage(
 65        EventId = UpdateRejectedEventId,
 66        Level = LogLevel.Warning,
 67        Message = "Update rejected by rate limiter. payload_type={PayloadType}, limiter={Limiter}, retry_after={RetryAft
 68    private static partial void LogUpdateRejected(
 69        ILogger logger,
 70        string payloadType,
 71        string limiter,
 72        TimeSpan? retryAfter,
 73        string policyName);
 74}