sharp-chat/SharpChatCommon/RateLimiter.cs
flashwave 5a7756894b
First bits of the Context overhaul.
Reintroduces separate contexts for users, channels, connections (now split into sessions and connections) and user-channel associations.
It builds which is as much assurance as I can give about the stability of this commit, but its also the bare minimum of what i like to commit sooooo
A lot of things still need to be broadcast through events throughout the application in order to keep states consistent but we'll cross that bridge when we get to it.
I really need to stop using that phrase thingy, I'm overusing it.
2025-05-03 02:49:51 +00:00

43 lines
1.6 KiB
C#

namespace SharpChat;
public class RateLimiter {
public const int DEFAULT_SIZE = 30;
public const int DEFAULT_MINIMUM_DELAY = 10000;
public const int DEFAULT_RISKY_OFFSET = 5;
private readonly int Size;
private readonly int MinimumDelay;
private readonly int RiskyOffset;
private readonly long[] TimePoints;
public RateLimiter(
int size = DEFAULT_SIZE,
int minDelay = DEFAULT_MINIMUM_DELAY,
int riskyOffset = DEFAULT_RISKY_OFFSET
) {
if(size < 2)
throw new ArgumentException("Size is too small.", nameof(size));
if(minDelay < 1000)
throw new ArgumentException("Minimum delay is inhuman.", nameof(minDelay));
if(riskyOffset != 0) {
if(riskyOffset >= size)
throw new ArgumentException("Risky offset may not be greater or equal to the size.", nameof(riskyOffset));
else if(riskyOffset < 0)
throw new ArgumentException("Risky offset may not be negative.", nameof(riskyOffset));
}
Size = size;
MinimumDelay = minDelay;
RiskyOffset = riskyOffset;
TimePoints = new long[Size];
}
public bool IsRisky => TimePoints[RiskyOffset] != 0 && TimePoints[RiskyOffset + 1] != 0 && TimePoints[RiskyOffset] + MinimumDelay >= TimePoints[Size - 1];
public bool IsExceeded => TimePoints[0] != 0 && TimePoints[1] != 0 && TimePoints[0] + MinimumDelay >= TimePoints[Size - 1];
public void Update() {
for(int i = 1; i < Size; ++i)
TimePoints[i - 1] = TimePoints[i];
TimePoints[Size - 1] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}