public static async Task <ITokenBucket> GetTokenBucketAsync(CustomerThrottle customerThrottle) { return(await TokenBuckets.BucketWithFixedIntervalRefillStrategy( capacity : (long)customerThrottle.MaximumRequestsPerSecond, refillTokens : (long)customerThrottle.MaximumRequestsPerSecond, period : oneSecond).ConfigureAwait(false)); }
private async Task <ITokenBucket> CreateAndStoreTokenBucketContext(CustomerThrottle customerThrottle) { object objNewTokenBucket = await TokenBucketFactory.GetTokenBucketAsync(customerThrottle).ConfigureAwait(false); CustomerThrottleContext newThrottleContext = CustomerThrottleContext.Create( customerThrottle: customerThrottle, tokenBucket: objNewTokenBucket); contextDict.AddOrUpdate(customerThrottle.CustomerIdentityKey, newThrottleContext, updateValueFactory: (factoryKey, factoryValue) => { return(newThrottleContext); }); return((ITokenBucket)objNewTokenBucket); }
/// <summary> /// Executes the delegate function on a throttled basis. /// /// When this overload is called and no CancellationToken was passed at instance construction, /// then the internal cancellation logic will use the CancellationToken passed to this method, and the same CancellationToken will be passed to the delegate. /// When this overload is called and a CancellationToken was passed at instance construction, /// then the internal cancellation logic will use the instance CancellationToken, and the CancellationToken passed to this overload will be passed to the delegate. /// </summary> /// <param name="customerThrottle">Determines which throttle-rate to use. If you pass a customerThrottle with an ID that hasn't been seen previously by the instance, /// then a new underlying TokenBucket is created. If you pass a customerThrottle with an ID that has been seen previously by the instance, then you'll get the /// underlying TokenBucket already associated with that ID. /// If you want to change the throttling rate associated with a particular ID, just pass in a new customerThrottle object with the new maximumRequestsPerSecond property /// value and the same ID.</param> /// <param name="request">The request object (of type TRequest) to pass to the delegate.</param> /// <param name="cancellationToken"></param> /// <returns></returns> public async Task <TResponse> ExecuteThrottledAsync(CustomerThrottle customerThrottle, TRequest request, CancellationToken cancellationToken) { CheckIfThisInstanceIsDisposed_ForPlacementAtTopOfPublicMethods(); if (customerThrottle == null) { throw new ArgumentNullException(nameof(customerThrottle)); } customerThrottle.ValidateArguments(); if (this.cancellationToken.IsNotNone()) { return(await ExecuteThrottledAsync(customerThrottle, request, this.cancellationToken, cancellationToken).ConfigureAwait(false)); } else { return(await ExecuteThrottledAsync(customerThrottle, request, cancellationToken, cancellationToken).ConfigureAwait(false)); } }
private async Task <TResponse> ExecuteThrottledAsync(CustomerThrottle customerThrottle, TRequest request, CancellationToken cancellationTokenToCheckInternally, CancellationToken cancellationTokenToPassToDelegate) { ITokenBucket tokenBucket = null; if (customerThrottle.MaximumRequestsPerSecond > 0) { tokenBucket = await RetrieveMatchingTokenBucketContextOrMakeNew(customerThrottle).ConfigureAwait(false); if (cancellationTokenToCheckInternally.IsNotNone()) { cancellationTokenToCheckInternally.ThrowIfCancellationRequested(); } await tokenBucket.WaitConsumeAsync(1, cancellationTokenToCheckInternally).ConfigureAwait(false); } if (cancellationTokenToCheckInternally.IsNotNone()) { cancellationTokenToCheckInternally.ThrowIfCancellationRequested(); } return(await delegateFunction(request, cancellationTokenToPassToDelegate).ConfigureAwait(false)); }
private async Task <ITokenBucket> RetrieveMatchingTokenBucketContextOrMakeNew(CustomerThrottle customerThrottle) { ITokenBucket tokenBucket; if (contextDict.TryGetValue(customerThrottle.CustomerIdentityKey, out var storedThrottle)) { if (!storedThrottle.CustomerThrottle.Equals(customerThrottle)) { tokenBucket = await CreateAndStoreTokenBucketContext(customerThrottle).ConfigureAwait(false); } else // if storedThrottle.CustomerThrottle.Equals(customerThrottle) { tokenBucket = (ITokenBucket)storedThrottle.TokenBucket; } } else // (! contextDict.TryGetValue(customerThrottle.CustomerIdentityKey, out var storedThrottle)) { tokenBucket = await CreateAndStoreTokenBucketContext(customerThrottle).ConfigureAwait(false); } return(tokenBucket); }