< Summary

Information
Class: Intentum.Distributed.Redis.RedisDistributedRateLimiter
Assembly: Intentum.Distributed.Redis
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.Distributed.Redis/RedisDistributedRateLimiter.cs
Line coverage
0%
Covered lines: 0
Uncovered lines: 17
Coverable lines: 17
Total lines: 33
Line coverage: 0%
Branch coverage
0%
Covered branches: 0
Total branches: 2
Branch coverage: 0%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)100%110%
TryAcquireAsync()0%220%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.Distributed.Redis/RedisDistributedRateLimiter.cs

#LineLine coverage
 1using Intentum.Distributed.RateLimiting;
 2using StackExchange.Redis;
 3
 4namespace Intentum.Distributed.Redis;
 5
 6public sealed class RedisDistributedRateLimiter : IDistributedRateLimiter
 7{
 8    private readonly IDatabase _db;
 9    private readonly string _keyPrefix;
 10
 011    public RedisDistributedRateLimiter(IConnectionMultiplexer connection, string keyPrefix = "intentum:ratelimit:")
 012    {
 013        _db = connection.GetDatabase();
 014        _keyPrefix = keyPrefix;
 015    }
 16
 17    public async Task<bool> TryAcquireAsync(string key, int limit, TimeSpan window, CancellationToken cancellationToken 
 018    {
 019        var redisKey = $"{_keyPrefix}{key}";
 020        var now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
 021        var windowStart = now - (long)window.TotalMilliseconds;
 22
 023        await _db.SortedSetRemoveRangeByScoreAsync(redisKey, double.MinValue, windowStart);
 024        var currentCount = await _db.SortedSetLengthAsync(redisKey);
 25
 026        if (currentCount >= limit)
 027            return false;
 28
 029        await _db.SortedSetAddAsync(redisKey, Guid.NewGuid().ToString(), now);
 030        await _db.KeyExpireAsync(redisKey, window);
 031        return true;
 032    }
 33}