How to build speed limit APIs with Observables?

I would like to create a simple calculator service that has one method for adding numbers. This method Addshould asyncand should limit the number of simultaneous calls made at a given time. For example, no more than 5 simultaneous calls per second. If the limit is exceeded, the call should throw an exception.

The class should look like this:

public class RateLimitingCalculator
{
    public async Task<int> Add(int a, int b) 
    {
        //...
    }
}

Any ideas? I would like to implement it using Reactive Extensions, but if it is better to use a different strategy, I would stick to this! Thank!!

+2
source share
1 answer

, Rx , - public IObservable<int> Add(IObservable<Tuple<int, int>> values), Enigmativity .

, , - . , :

public class RateLimitingCalculator
{
    private RateLimiter rateLimiter = new RateLimiter(5, TimeSpan.FromSeconds(1));

    public async Task<int> Add(int a, int b) 
    {
        rateLimiter.ThrowIfRateExceeded();

        //...
    }
}

RateLimiter , , :

class RateLimiter
{
    private readonly int rate;
    private readonly TimeSpan perTime;

    private DateTime secondStart = DateTime.MinValue;
    private int count = 0;

    public RateLimiter(int rate, TimeSpan perTime)
    {
        this.rate = rate;
        this.perTime = perTime;
    }

    public void ThrowIfRateExceeded()
    {
        var now = DateTime.UtcNow;

        if (now - secondStart > perTime)
        {
            secondStart = now;
            count = 1;
            return;
        }

        if (count >= rate)
            throw new RateLimitExceededException();

        count++;
    }
}
+1

Source: https://habr.com/ru/post/1649639/


All Articles