0 votes
by (2.0k points)

Is it possible to implement a feature that can limit the number of requests per second based on HttpRequestCreator?

I want to limit the number of Http requests per second based on HttpRequestCreator.
How can I implement this feature?

var creator = new HttpRequestCreator();
// 5 requests per one second
creator.SetRateLimit(5, 1000);

// creator waits appropriately and returns create
var request = creator.RateLimitCreate();

1 Answer

+1 vote
by (72.7k points)
selected by
 
Best answer

Request creation throttling is not implemented, but it can be added easily. For example like this:

public class ThrottlingHttpRequestCreator : HttpRequestCreator
{
    private int _max_count;
    private int _max_ms;
    private readonly LinkedList<long> _timestamps = new LinkedList<long>();

    public void SetRateLimit(int count, int milliseconds)
    {
        lock (_timestamps)
        {
            _max_count = count;
            _max_ms = milliseconds;
            _timestamps.Clear();
        }
    }

    public new HttpRequest Create(Uri uri)
    {
        long delay = 0;
        lock (_timestamps) // makes this thread-safe
        {
            if (_max_count > 0) // is throttling set?
            {
                var timestamp = Environment.TickCount64;
                if (_timestamps.Count == _max_count)
                {
                    // compute minimal time to create the request
                    long min = _timestamps.First() + _max_ms;
                    delay = min - timestamp;
                    _timestamps.RemoveFirst();
                    _timestamps.AddLast(Math.Max(min, timestamp));
                }
                else
                {
                    _timestamps.AddLast(timestamp);
                }
            }
        }

        if (delay > 0)
            Thread.Sleep(TimeSpan.FromMilliseconds(delay));

        return base.Create(uri);
    }

    public new HttpRequest Create(string uri)
    {
        return Create(new Uri(uri));
    }
}

If you want to use the Register() method, the new class has to implement IWebRequestCreate interface like this:

public class ThrottlingHttpRequestCreator : HttpRequestCreator, IWebRequestCreate
{
    ...

    WebRequest IWebRequestCreate.Create(Uri uri)
    {
        return Create(uri);
    }

    public new void Register()
    {
        WebRequest.RegisterPrefix("http://", this);
        WebRequest.RegisterPrefix("https://", this);
    }
}
by (2.0k points)
This is the best solution.
Thank you.
...