HallPass 0.0.12
See the version list below for details.
dotnet add package HallPass --version 0.0.12
NuGet\Install-Package HallPass -Version 0.0.12
<PackageReference Include="HallPass" Version="0.0.12" />
paket add HallPass --version 0.0.12
#r "nuget: HallPass, 0.0.12"
// Install HallPass as a Cake Addin
#addin nuget:?package=HallPass&version=0.0.12
// Install HallPass as a Cake Tool
#tool nuget:?package=HallPass&version=0.0.12
HallPass - PRE-RELEASE
Client-side rate limiter library for .NET to help client-side developers respect the rate limits of the APIs that they consume.
Installation
// nuget package manager
Install-Package HallPass
// dotnet cli
dotnet add package HallPass
Usage
Configuration
using HallPass;
...
// HallPass extension method
builder.Services.UseHallPass(config =>
{
// local buckets, for single instance
config.UseTokenBucket("api.foo.com/users", requestsPerPeriod: 100, periodDuration: TimeSpan.FromMinutes(15));
// can also use a Func<HttpRequestMessage, bool> to resolve whether to throttle or not
config.UseTokenBucket(
httpRequestMessage => httpRequestMessage.RequestUri.ToString().Contains("api.foo.com/posts"),
1000,
TimeSpan.FromMinutes(1));
// and we can even use the service collection, via Func<IServiceProvider, bool> to determine whether to throttle or not
config.UseTokenBucket(
services => ...something returning true/false...,
50000,
TimeSpan.FromHours(24));
// remote buckets, for coordinating clusters of services
config.UseTokenBucket("api.bar.com/statuses", 50, TimeSpan.FromMinutes(1)).ForMultipleInstances("my-client-id", "my-client-secret");
});
Usage - Throttle a single call
using HallPass;
...
class MyService
{
private readonly IHttpClientFactory _httpClientFactory;
public MyService(IHttpClientFactory httpClientFactory)
{
_httpClientFactory = httpClientFactory;
}
public async Task<FooUser> GetFooUserAsync(string userId, CancellationToken token = default)
{
// HallPass extension method
HttpClient httpClient = _httpClientFactory.CreateHallPassClient();
...
// this line will wait, if necessary, so the frequency remains within 100 requests per 15 minutes WITHIN THIS SINGLE APP, as defined in the configuration
await httpClient.GetAsync($"https://api.foo.com/users/{userId}", token);
}
}
Usage - Throttle a bunch of calls in a loop
HallPass works for synchronous loops (within async methods) by simply awaiting until it has permission to proceed based on the configuration.
var userIds = Enumerable.Range(1, 500);
foreach (var userId in userIds)
{
// this line will wait, if necessary, so the frequency remains within 100 requests per 15 minutes WITHIN THIS SINGLE APP, as defined in the configuration
await httpClient.GetAsync($"https://api.foo.com/users/{userId}", token);
}
Usage - Throttle a bunch of calls concurrently
HallPass is also thread-safe, working as expected for concurrent bunches of requests.
var tasks = Enumerable
.Range(1, 500)
.Select(userId => Task.Run(async () =>
{
// this line will wait, if necessary, so the frequency remains within 100 requests per 15 minutes WITHIN THIS SINGLE APP, as defined in the configuration
await httpClient.GetAsync($"https://api.foo.com/users/{userId}", token);
}))
.ToList();
await Task.WhenAll(tasks);
COMING SOON: Throttle a Bunch of Calls Across Distributed Systems
Soon, HallPass will be able to throttle calls across distributed systems. If you have multiple instances of an application running at once, but need to respect a single external API rate limit, or if you have multiple different applications running but still need to respect a single external API rate limit between all instances and applications, you'd be able to do so with minimal code changes.
This will be a paid service, and the HallPass API itself will be rate-limited (with basic throttling and retries handled via the SDK code). We're still finalizing the pricing model, but hope to have a free tier available to demo soon!
Configuration
using HallPass;
...
// HallPass extension method
builder.Services.UseHallPass(config =>
{
// remote buckets, for coordinating clusters of services
config
.UseTokenBucket("api.bar.com/statuses", 50, TimeSpan.FromMinutes(1))
// client id and secret provided when registering an app in your HallPass dashboard
.ForMultipleInstances("my-client-id", "my-client-secret");
});
Usage
using HallPass;
...
HttpClient httpClient = _httpClientFactory.CreateHallPassClient();
/* this line will wait, if necessary, so the frequency remains within 50 requests
per 1 minute ACROSS ALL DISTRIBUTED INSTANCES for the given HallPass client_id,
as defined in the configuration */
await httpClient.GetAsync($"https://api.bar.com/statuses");
HallPass will take care of registering individual instances, "fairly" dolling out permissions, and tracking the global rate limit for your account/app and its usage on our servers.
HallPass will never know what endpoints you're calling, because the actual API call is still handled locally within each application. All that HallPass receives is an encrypted unique ID representing each scoped throttle group, and the bucket type used for that key.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- LazyCache (>= 2.4.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.6.2 | 223 | 5/1/2023 |
0.6.1 | 416 | 8/18/2022 |
0.6.0 | 415 | 8/18/2022 |
0.5.5 | 396 | 8/17/2022 |
0.5.4 | 414 | 8/17/2022 |
0.5.3 | 400 | 8/17/2022 |
0.5.2 | 388 | 8/15/2022 |
0.5.1 | 455 | 8/15/2022 |
0.5.0 | 439 | 8/1/2022 |
0.4.1 | 419 | 7/29/2022 |
0.4.0 | 424 | 7/29/2022 |
0.3.0 | 430 | 7/28/2022 |
0.2.7 | 435 | 7/28/2022 |
0.2.6 | 407 | 7/28/2022 |
0.2.4 | 422 | 7/27/2022 |
0.2.3 | 423 | 7/21/2022 |
0.2.2 | 417 | 7/18/2022 |
0.2.1 | 390 | 7/15/2022 |
0.2.0 | 435 | 7/14/2022 |
0.1.3 | 453 | 7/7/2022 |
0.1.2 | 432 | 7/5/2022 |
0.1.1 | 441 | 6/8/2022 |
0.1.0 | 403 | 6/7/2022 |
0.0.18 | 404 | 6/7/2022 |
0.0.17 | 424 | 6/7/2022 |
0.0.16 | 394 | 6/6/2022 |
0.0.15 | 424 | 6/6/2022 |
0.0.14 | 426 | 6/6/2022 |
0.0.13 | 425 | 6/6/2022 |
0.0.12 | 431 | 6/6/2022 |
0.0.11 | 396 | 6/4/2022 |
0.0.10 | 452 | 6/3/2022 |
0.0.9 | 427 | 5/31/2022 |
0.0.8 | 416 | 5/31/2022 |
0.0.7 | 425 | 5/31/2022 |
0.0.6 | 413 | 5/31/2022 |
0.0.5 | 408 | 5/31/2022 |
0.0.4 | 443 | 5/31/2022 |
0.0.3 | 417 | 5/31/2022 |
0.0.2 | 424 | 5/31/2022 |
0.0.1 | 430 | 5/11/2022 |