SimpleRateLimiter is.. well.. just that. A short, sweet and to the point rate limiter (with interrupt-ability!). Implement it however you like. Use it in a loop or implement it into a delegate handler. Create a derivative of your favorite class and use it in otherwise pointless overrides that just point back to base
. Whatever you want.
Here's a more than pointless ConsoleApp demonstrating exactly how this works.
using Oz.RateLimiting;
internal static async Task Main() {
// create a new limiter @ 5 requests per 1 second
var rateLimiter = new SimpleRateLimiter(5, new TimeSpan(0, 0, 0, 1));
var cancellationToken = new CancellationToken();
// try spamming the console
for (int i = 1; i <= 10; i++) {
// wait for any potential hold times
if (await rateLimiter.WaitForAvailabilityAsync(cancellationToken)) {
// we're safe to continue
Console.WriteLine($"Request #{i} - DateTime.Now: {DateTime.Now}");
}
}
}
using Oz.RateLimiting;
Let's get setup for 200 requests per hour.
var rateLimiter = new SimpleRateLimiter(200, new TimeSpan(0, 1));
Or if maybe this is easier to read. Albeit, definitely less efficient.
var now = DateTime.Now;
var oneMinuteFromNow = now.AddHours(1);
var oneMinuteWindow = oneMinuteFromNow - now;
var rateLimiter = new SimpleRateLimiter(200, oneMinuteWindow);
Let's make some API calls to jsonplaceholder (a free, fake API for testing).
var cancellationToken = new CancellationToken();
var httpClient = new HttpClient();
for (int i = 1; i <= 5000; i++) {
var request = new HttpRequestMessage(HttpMethod.Get,
$"https://jsonplaceholder.typicode.com/photos/{i}");
if (rateLimiter.WaitForAvailabilityAsync(cancellationToken)) {
var response = await client.SendAsync(request);
}
}