Every web application calls external web services and it's often desired to limit the number of requests we send to external web services in a duration of time for example we want to send a maximum of 100 requests from our application to XYZ external web service per minute so in that case, we would like to throttle the outgoing requests going to web services.
Introduction
RateLimiter Nuget Package
Features of RateLimiter
- Easy to use
- Fully asynchronous: lower resource usage than thread sleep
- Cancellable via CancellationToken
- Thread-safe so you can share time constraints object to rate limit different threads using the same resource
- Composable: the ability to compose different rate limits in one constraint
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
// Defines RateLimiter
var rateLimiter = TimeLimiter.GetFromMaxCountByInterval(3, TimeSpan.FromMinutes(1));
// Applies the RateLimiter to all the call to IStudentClient
services
.AddRefitClient<IStudentClient>()
.ConfigureHttpClient(c => c.BaseAddress = new Uri("https://localhost:44391"))
.AddHttpMessageHandler(() => rateLimiter.AsDelegatingHandler());
services.AddSingleton(_ => rateLimiter);
}
The above code is written in the ConfigureServices method in Startup.cs file.
We also have to create an Extension method for AsDelegatingHandler() method
public static class DispatcherExtension
{
private sealed class DispatcherDelegatingHandler : DelegatingHandler
{
private readonly ComposableAsync.IDispatcher _Dispatcher;
public DispatcherDelegatingHandler(ComposableAsync.IDispatcher dispatcher)
{
_Dispatcher = dispatcher;
}
protected override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request,
CancellationToken cancellationToken)
{
return _Dispatcher.Enqueue(() =>
base.SendAsync(request, cancellationToken), cancellationToken);
}
}
public static DelegatingHandler AsDelegatingHandler(
this ComposableAsync.IDispatcher dispatcher)
{
return new DispatcherDelegatingHandler(dispatcher);
}
}
As you see above we are applying RateLimiter for all the calls going to IStudentClient and the rate is defined as 3 requests per minute. If the application sends more than 3 requests then it waits for the duration till 1 minute completes and then sends the request. You might have observed we are not using general HttpClient or WebClient to send the request and instead of using Refit Nuget Library so you can check this article regarding Refit Nuget Library which simplifies the call to external web service.
As you can see in the above image the 3rd request takes time till 1 minute completes and the timer is reset again.
Share This Post
Support Me