File: System\Threading\RateLimiting\TranslatingLimiter.cs
Web Access
Project: src\src\libraries\System.Threading.RateLimiting\src\System.Threading.RateLimiting.csproj (System.Threading.RateLimiting)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System.Threading.Tasks;
 
namespace System.Threading.RateLimiting
{
    internal sealed class TranslatingLimiter<TInner, TResource> : PartitionedRateLimiter<TResource>
    {
        private readonly PartitionedRateLimiter<TInner> _innerRateLimiter;
        private readonly Func<TResource, TInner> _keyAdapter;
        private readonly bool _disposeInnerLimiter;
 
        private int _disposed;
 
        public TranslatingLimiter(PartitionedRateLimiter<TInner> inner, Func<TResource, TInner> keyAdapter, bool leaveOpen)
        {
            _innerRateLimiter = inner;
            _keyAdapter = keyAdapter;
            _disposeInnerLimiter = !leaveOpen;
        }
 
        public override RateLimiterStatistics? GetStatistics(TResource resource)
        {
            ThrowIfDispose();
            TInner key = _keyAdapter(resource);
            return _innerRateLimiter.GetStatistics(key);
        }
 
        protected override RateLimitLease AttemptAcquireCore(TResource resource, int permitCount)
        {
            ThrowIfDispose();
            TInner key = _keyAdapter(resource);
            return _innerRateLimiter.AttemptAcquire(key, permitCount);
        }
 
        protected override ValueTask<RateLimitLease> AcquireAsyncCore(TResource resource, int permitCount, CancellationToken cancellationToken)
        {
            ThrowIfDispose();
            TInner key = _keyAdapter(resource);
            return _innerRateLimiter.AcquireAsync(key, permitCount, cancellationToken);
        }
 
        protected override void Dispose(bool disposing)
        {
            if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0)
            {
                if (_disposeInnerLimiter)
                {
                    _innerRateLimiter.Dispose();
                }
            }
        }
 
        protected override ValueTask DisposeAsyncCore()
        {
            if (Interlocked.CompareExchange(ref _disposed, 1, 0) == 0)
            {
                if (_disposeInnerLimiter)
                {
                    return _innerRateLimiter.DisposeAsync();
                }
            }
            return default(ValueTask);
        }
 
        private void ThrowIfDispose()
        {
            if (_disposed == 1)
            {
                throw new ObjectDisposedException(nameof(PartitionedRateLimiter<TResource>));
            }
        }
    }
}