Untitled

 avatar
unknown
plain_text
6 months ago
2.9 kB
2
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