I'd like to seek advice on my implementation of rate controlling or throtting tool which implemented by C#.NET 6.
- correctness of implementation
- performance issue or any improvement can be done.
public sealed class RateLimiter : IDisposable
{
private const string KEY = "RL";
private readonly Timer _timer;
private readonly ConcurrentDictionary<string, byte> _token = new();
public RateLimiter(TimeSpan window, int limit)
{
double total = window.TotalMilliseconds;
if (total <= 0)
{
throw new ArgumentException("window can not be zero or negative", nameof(window));
}
if (limit <= 0)
{
throw new ArgumentException("limit can not be zero or negative", nameof(limit));
}
double interval = total / limit;
_timer = new Timer(interval);
_timer.AutoReset = true;
_timer.Elapsed += Timer_Elapsed;
_timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
_token.TryAdd(KEY, byte.MinValue);
}
public bool TryAcquire()
{
return _token.TryRemove(KEY, out _);
}
public void Dispose()
{
_timer.Elapsed -= Timer_Elapsed;
_timer.Stop();
_timer.Close();
}
}
Use case:
// create RateLimiter instance, set the rate to be 10 messages per second
_throttle = new RateLimiter(TimeSpan.FromSeconds(1), 10);
// if within limit, then publish price
if (_throttle.TryAcquire())
{
// publish stock price to downstream
}