Untitled
unknown
plain_text
a year ago
2.9 kB
3
Indexable
using System;
using System.Threading;
using System.Collections.Generic;
public class Consumer {
private int count;
private DateTime thisWindowStart;
private DateTime blockTime;
public Consumer(DateTime thisWindowStart) {
this.thisWindowStart = thisWindowStart;
}
public void IncrCounter() {
this.count++;
}
public bool PastLimit(int allowedCount) {
return this.count > allowedCount;
}
public bool IsWithinWindow(DateTime now, int period) {
return (now - this.thisWindowStart).TotalSeconds <= period;
}
public void ResetWindow(DateTime windowStart) {
this.count = 1;
this.thisWindowStart = windowStart;
}
public void SetBlockTime(DateTime blockTime) {
this.blockTime = blockTime;
}
public bool IsWithinBlockTime(DateTime now, int period) {
return (now - this.blockTime).TotalSeconds <= period;
}
}
public class TokenRateLimiter {
private int numRequest;
private int windowPeriod;
private int blockingPeriod;
private Dictionary<string, Consumer> consumers;
public TokenRateLimiter(int numRequest, int period, int blocking) {
this.numRequest = numRequest;
this.windowPeriod = period;
this.blockingPeriod = blocking;
this.consumers = new Dictionary<string, Consumer>();
}
public bool AllowRequest(string consumer) {
DateTime now = DateTime.Now;
bool allowed = true;
Consumer thisConsumer = new Consumer(now);
if (this.consumers.ContainsKey(consumer)) {
thisConsumer = this.consumers[consumer];
} else {
this.consumers[consumer] = thisConsumer;
}
if (thisConsumer.IsWithinWindow(now, this.windowPeriod)) {
thisConsumer.IncrCounter();
if (thisConsumer.PastLimit(this.numRequest)) {
thisConsumer.SetBlockTime(now);
allowed = false;
}
} else if (thisConsumer.IsWithinBlockTime(now, this.blockingPeriod)) {
allowed = false;
} else {
thisConsumer.ResetWindow(now);
}
return allowed;
}
}
public class Program
{
static void Main(string[] args)
{
var rateLimiter = new TokenRateLimiter(3, 1, 3);
Thread tselThread = new Thread(() =>
{
retry("tsel", 300, rateLimiter);
});
Thread xlThread = new Thread(() =>
{
retry("xl", 500, rateLimiter);
});
tselThread.Start();
xlThread.Start();
tselThread.Join();
xlThread.Join();
}
static void retry(string consumer, int interval, TokenRateLimiter rateLimiter)
{
while (true)
{
bool allowed = rateLimiter.AllowRequest(consumer);
if (allowed)
{
Console.WriteLine($"Request allowed for token '{consumer}'.");
}
else
{
Console.WriteLine($"Rate limit exceeded for token '{consumer}'. Try again later.");
}
Thread.Sleep(interval); // Sleep to avoid busy waiting
}
}
}Editor is loading...
Leave a Comment