# System.Threading.RateLimiting

``` diff
+namespace System.Threading.RateLimiting {
+    public sealed class ConcurrencyLimiter : RateLimiter {
+        public ConcurrencyLimiter(ConcurrencyLimiterOptions options);
+        public override TimeSpan? IdleDuration { get; }
+        protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken = default(CancellationToken));
+        protected override RateLimitLease AttemptAcquireCore(int permitCount);
+        protected override void Dispose(bool disposing);
+        protected override ValueTask DisposeAsyncCore();
+        public override RateLimiterStatistics? GetStatistics();
+    }
+    public sealed class ConcurrencyLimiterOptions {
+        public ConcurrencyLimiterOptions();
+        public int PermitLimit { get; set; }
+        public int QueueLimit { get; set; }
+        public QueueProcessingOrder QueueProcessingOrder { get; set; }
+    }
+    public sealed class FixedWindowRateLimiter : ReplenishingRateLimiter {
+        public FixedWindowRateLimiter(FixedWindowRateLimiterOptions options);
+        public override TimeSpan? IdleDuration { get; }
+        public override bool IsAutoReplenishing { get; }
+        public override TimeSpan ReplenishmentPeriod { get; }
+        protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken = default(CancellationToken));
+        protected override RateLimitLease AttemptAcquireCore(int permitCount);
+        protected override void Dispose(bool disposing);
+        protected override ValueTask DisposeAsyncCore();
+        public override RateLimiterStatistics? GetStatistics();
+        public override bool TryReplenish();
+    }
+    public sealed class FixedWindowRateLimiterOptions {
+        public FixedWindowRateLimiterOptions();
+        public bool AutoReplenishment { get; set; }
+        public int PermitLimit { get; set; }
+        public int QueueLimit { get; set; }
+        public QueueProcessingOrder QueueProcessingOrder { get; set; }
+        public TimeSpan Window { get; set; }
+    }
+    public static class MetadataName {
+        public static MetadataName<string> ReasonPhrase { get; }
+        public static MetadataName<TimeSpan> RetryAfter { get; }
+        public static MetadataName<T> Create<T>(string name);
+    }
+    public sealed class MetadataName<T> : IEquatable<MetadataName<T>> {
+        public MetadataName(string name);
+        public string Name { get; }
+        public override bool Equals([NotNullWhenAttribute(true)] object? obj);
+        public bool Equals(MetadataName<T>? other);
+        public override int GetHashCode();
+        public static bool operator ==(MetadataName<T> left, MetadataName<T> right);
+        public static bool operator !=(MetadataName<T> left, MetadataName<T> right);
+        public override string ToString();
+    }
+    public static class PartitionedRateLimiter {
+        public static PartitionedRateLimiter<TResource> Create<TResource, TPartitionKey>(Func<TResource, RateLimitPartition<TPartitionKey>> partitioner, IEqualityComparer<TPartitionKey>? equalityComparer = null);
+        public static PartitionedRateLimiter<TResource> CreateChained<TResource>(params PartitionedRateLimiter<TResource>[] limiters);
+    }
+    public abstract class PartitionedRateLimiter<TResource> : IAsyncDisposable, IDisposable {
+        protected PartitionedRateLimiter();
+        public ValueTask<RateLimitLease> AcquireAsync(TResource resource, int permitCount = 1, CancellationToken cancellationToken = default(CancellationToken));
+        protected abstract ValueTask<RateLimitLease> AcquireAsyncCore(TResource resource, int permitCount, CancellationToken cancellationToken);
+        public RateLimitLease AttemptAcquire(TResource resource, int permitCount = 1);
+        protected abstract RateLimitLease AttemptAcquireCore(TResource resource, int permitCount);
+        public void Dispose();
+        protected virtual void Dispose(bool disposing);
+        public ValueTask DisposeAsync();
+        protected virtual ValueTask DisposeAsyncCore();
+        public abstract RateLimiterStatistics? GetStatistics(TResource resource);
+        public PartitionedRateLimiter<TOuter> WithTranslatedKey<TOuter>(Func<TOuter, TResource> keyAdapter, bool leaveOpen);
+    }
+    public enum QueueProcessingOrder {
+        NewestFirst = 1,
+        OldestFirst = 0,
+    }
+    public abstract class RateLimiter : IAsyncDisposable, IDisposable {
+        protected RateLimiter();
+        public abstract TimeSpan? IdleDuration { get; }
+        public ValueTask<RateLimitLease> AcquireAsync(int permitCount = 1, CancellationToken cancellationToken = default(CancellationToken));
+        protected abstract ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken);
+        public RateLimitLease AttemptAcquire(int permitCount = 1);
+        protected abstract RateLimitLease AttemptAcquireCore(int permitCount);
+        public void Dispose();
+        protected virtual void Dispose(bool disposing);
+        public ValueTask DisposeAsync();
+        protected virtual ValueTask DisposeAsyncCore();
+        public abstract RateLimiterStatistics? GetStatistics();
+    }
+    public class RateLimiterStatistics {
+        public RateLimiterStatistics();
+        public long CurrentAvailablePermits { get; set; }
+        public long CurrentQueuedCount { get; set; }
+        public long TotalFailedLeases { get; set; }
+        public long TotalSuccessfulLeases { get; set; }
+    }
+    public abstract class RateLimitLease : IDisposable {
+        protected RateLimitLease();
+        public abstract bool IsAcquired { get; }
+        public abstract IEnumerable<string> MetadataNames { get; }
+        public void Dispose();
+        protected virtual void Dispose(bool disposing);
+        public virtual IEnumerable<KeyValuePair<string, object?>> GetAllMetadata();
+        public abstract bool TryGetMetadata(string metadataName, out object? metadata);
+        public bool TryGetMetadata<T>(MetadataName<T> metadataName, [MaybeNullAttribute] out T metadata);
+    }
+    public static class RateLimitPartition {
+        public static RateLimitPartition<TKey> Get<TKey>(TKey partitionKey, Func<TKey, RateLimiter> factory);
+        public static RateLimitPartition<TKey> GetConcurrencyLimiter<TKey>(TKey partitionKey, Func<TKey, ConcurrencyLimiterOptions> factory);
+        public static RateLimitPartition<TKey> GetFixedWindowLimiter<TKey>(TKey partitionKey, Func<TKey, FixedWindowRateLimiterOptions> factory);
+        public static RateLimitPartition<TKey> GetNoLimiter<TKey>(TKey partitionKey);
+        public static RateLimitPartition<TKey> GetSlidingWindowLimiter<TKey>(TKey partitionKey, Func<TKey, SlidingWindowRateLimiterOptions> factory);
+        public static RateLimitPartition<TKey> GetTokenBucketLimiter<TKey>(TKey partitionKey, Func<TKey, TokenBucketRateLimiterOptions> factory);
+    }
+    public struct RateLimitPartition<TKey> {
+        public RateLimitPartition(TKey partitionKey, Func<TKey, RateLimiter> factory);
+        public Func<TKey, RateLimiter> Factory { get; }
+        public TKey PartitionKey { get; }
+    }
+    public abstract class ReplenishingRateLimiter : RateLimiter {
+        protected ReplenishingRateLimiter();
+        public abstract bool IsAutoReplenishing { get; }
+        public abstract TimeSpan ReplenishmentPeriod { get; }
+        public abstract bool TryReplenish();
+    }
+    public sealed class SlidingWindowRateLimiter : ReplenishingRateLimiter {
+        public SlidingWindowRateLimiter(SlidingWindowRateLimiterOptions options);
+        public override TimeSpan? IdleDuration { get; }
+        public override bool IsAutoReplenishing { get; }
+        public override TimeSpan ReplenishmentPeriod { get; }
+        protected override ValueTask<RateLimitLease> AcquireAsyncCore(int permitCount, CancellationToken cancellationToken = default(CancellationToken));
+        protected override RateLimitLease AttemptAcquireCore(int permitCount);
+        protected override void Dispose(bool disposing);
+        protected override ValueTask DisposeAsyncCore();
+        public override RateLimiterStatistics? GetStatistics();
+        public override bool TryReplenish();
+    }
+    public sealed class SlidingWindowRateLimiterOptions {
+        public SlidingWindowRateLimiterOptions();
+        public bool AutoReplenishment { get; set; }
+        public int PermitLimit { get; set; }
+        public int QueueLimit { get; set; }
+        public QueueProcessingOrder QueueProcessingOrder { get; set; }
+        public int SegmentsPerWindow { get; set; }
+        public TimeSpan Window { get; set; }
+    }
+    public sealed class TokenBucketRateLimiter : ReplenishingRateLimiter {
+        public TokenBucketRateLimiter(TokenBucketRateLimiterOptions options);
+        public override TimeSpan? IdleDuration { get; }
+        public override bool IsAutoReplenishing { get; }
+        public override TimeSpan ReplenishmentPeriod { get; }
+        protected override ValueTask<RateLimitLease> AcquireAsyncCore(int tokenCount, CancellationToken cancellationToken = default(CancellationToken));
+        protected override RateLimitLease AttemptAcquireCore(int tokenCount);
+        protected override void Dispose(bool disposing);
+        protected override ValueTask DisposeAsyncCore();
+        public override RateLimiterStatistics? GetStatistics();
+        public override bool TryReplenish();
+    }
+    public sealed class TokenBucketRateLimiterOptions {
+        public TokenBucketRateLimiterOptions();
+        public bool AutoReplenishment { get; set; }
+        public int QueueLimit { get; set; }
+        public QueueProcessingOrder QueueProcessingOrder { get; set; }
+        public TimeSpan ReplenishmentPeriod { get; set; }
+        public int TokenLimit { get; set; }
+        public int TokensPerPeriod { get; set; }
+    }
+}
```

