dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.17k stars 4.72k forks source link

[API Proposal]: Be able to skip the Chain in ChainedPartitionedRateLimiter #73513

Open Kahbazi opened 2 years ago

Kahbazi commented 2 years ago

Background and motivation

Let's say we want to chain multiple limiter together. Limiters based on IP, Username and Endpoint. Now if I want to skip limiters for some IPs, I could call GetNoLimiter() for them but the chain will continue and those requests could be limited based on username or endpoints.

I suggest to add an overload for GetNoLimiter(bool skipChain). This limiter could return a leases with certain metadata and ChainedPartitionedRateLimiter could skip the chain if the metadata exists.

cc/ @BrennanConroy @halter73

API Proposal

namespace System.Threading.RateLimiting;

public static class RateLimitPartition
{
+    public static RateLimitPartition<TKey> GetNoLimiter<TKey>(TKey partitionKey, bool skipChain)
}

API Usage

var limiter1 = PartitionedRateLimiter.Create<string, int>(resource =>
{
    if ( _resourceWithNoRateLimit.Contains(resource)
    {
        return RateLimitPartition.GetNoLimiter(resource, skipChain: true);
    }
    else
    {
        return RateLimitPartition.GetConcurrencyLimiter(1, _ => new ConcurrencyLimiterOptions { ... });
    }
});

var limiter2 = PartitionedRateLimiter.Create<string, int>(resource =>
{
    return RateLimitPartition.GetConcurrencyLimiter(resource, _ => new ConcurrencyLimiterOptions { ... });
});

var chainedLimiter = PartitionedRateLimiter.CreateChained<string>(limiter1, limiter2);

Alternative Designs

No response

Risks

No response

dotnet-issue-labeler[bot] commented 2 years ago

I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.

ghost commented 2 years ago

Tagging subscribers to this area: @mangod9 See info in area-owners.md if you want to be subscribed.

Issue Details
### Background and motivation Let's say we want to chain multiple limiter together. Limiters based on IP, Username and Endpoint. Now if I want to skip limiters for some IPs, I could call `GetNoLimiter()` for them but the chain will continue and those requests could be limited based on username or endpoints. I suggest to add an overload for `GetNoLimiter(bool skipChain)`. This limiter could return a leases with certain metadata and `ChainedPartitionedRateLimiter` could skip the chain if the metadata exists. cc/ @BrennanConroy @halter73 ### API Proposal ```diff namespace System.Threading.RateLimiting; public static class RateLimitPartition { + public static RateLimitPartition GetNoLimiter(TKey partitionKey, bool skipChain) } ``` ### API Usage ```csharp var limiter1 = PartitionedRateLimiter.Create(resource => { if ( _resourceWithNoRateLimit.Contains(resource) { return RateLimitPartition.GetNoLimiter(resource, skipChain: true); } else { return RateLimitPartition.GetConcurrencyLimiter(1, _ => new ConcurrencyLimiterOptions { ... }); } }); var limiter2 = PartitionedRateLimiter.Create(resource => { return RateLimitPartition.GetConcurrencyLimiter(resource, _ => new ConcurrencyLimiterOptions { ... }); }); var chainedLimiter = PartitionedRateLimiter.CreateChained(limiter1, limiter2); ``` ### Alternative Designs _No response_ ### Risks _No response_
Author: Kahbazi
Assignees: -
Labels: `api-suggestion`, `area-System.Threading`, `untriaged`
Milestone: -