Simple way to rate limit HttpClient requests

后端 未结 3 1357
终归单人心
终归单人心 2020-12-28 21:26

I am using the HTTPClient in System.Net.Http to make requests against an API. The API is limited to 10 requests per second.

My code is roughly like so:



        
3条回答
  •  青春惊慌失措
    2020-12-28 22:00

    UPDATED ANSWER

    My ProcessItems method makes 1-4 API calls depending on the item. So with a batch size of 10 I still exceed the rate limit.

    You need to implement a rolling window in SendRequestAsync. A queue containing timestamps of each request is a suitable data structure. You dequeue entries with a timestamp older than 10 seconds. As it so happens, there is an implementation as an answer to a similar question on SO.

    ORIGINAL ANSWER

    May still be useful to others

    One straightforward way to handle this is to batch your requests in groups of 10, run those concurrently, and then wait until a total of 10 seconds has elapsed (if it hasn't already). This will bring you in right at the rate limit if the batch of requests can complete in 10 seconds, but is less than optimal if the batch of requests takes longer. Have a look at the .Batch() extension method in MoreLinq. Code would look approximately like

    foreach (var taskList in tasks.Batch(10))
    {
        Stopwatch sw = Stopwatch.StartNew(); // From System.Diagnostics
        await Task.WhenAll(taskList.ToArray());
        if (sw.Elapsed.TotalSeconds < 10.0) 
        {
            // Calculate how long you still have to wait and sleep that long
            // You might want to wait 10.5 or 11 seconds just in case the rate
            // limiting on the other side isn't perfectly implemented
        }
    }
    

提交回复
热议问题