I am trying to throttle a loop (which is sending messages) to a particular number of messages per second. _throttle
is the number of messages per second.
My initial algorithm is depicted below, but the delays are not smooth.
What improvements can I make to smooth out the rather bumpy delays and bursts of messages.
I have played around with the tick, and the interval max, but the inbound count is so large it's hard to compensate. The maximum rate I can achieve with the throttle off in my implementation is about 15000/second. I am testing with rates between 300 and 1000 per second, so I am trying to slow it down quite a bit.
private class ThrottleCalculator
{
private readonly int _throttle;
private DateTime _lastCalculation = DateTime.Now;
private int _count = 0;
private int _interval = 0;
public ThrottleCalculator(int throttle)
{
this._throttle = throttle;
}
public async Task CalculateThrottle()
{
this._count += 1;
var elapsed = DateTime.Now.Subtract(this._lastCalculation).TotalMilliseconds;
var tick = 50;
if (elapsed > tick)
{
this._lastCalculation = DateTime.Now;
int projection = this._count * (1000 / tick);
var errorTerm = this._throttle - projection;
this._interval = this._interval - errorTerm;
if (this._interval < 0)
this._interval = 0;
// this is often several thousand, so I have to limit.
if (this._interval > 100)
this._interval = 100;
await Task.Delay(this._interval);
this._count = 0;
}
}
}
The code that uses this just calls this every iteration.
var throttle = new ThrottleCalculator(600); // 600/s
while (message = getMessage())
{
... // do stuff with message.
if (throttle != null)
await throttle.CalculateThrottle();