コード例 #1
0
ファイル: LeakyBucket.cs プロジェクト: useric/FinanceSharp
        /// <summary>
        ///      Blocks until the specified number of tokens are available for consumption
        ///      and then consumes that number of tokens.
        /// </summary>
        /// <param name="tokens">The number of tokens to consume</param>
        /// <param name="timeout">The maximum amount of time, in milliseconds, to block. An exception is
        ///      throw in the event it takes longer than the stated timeout to consume the requested number
        ///      of tokens</param>
        public void Consume(long tokens, long timeout = Timeout.Infinite)
        {
            if (timeout < Timeout.Infinite)
            {
                throw new ArgumentOutOfRangeException(nameof(timeout),
                                                      "Invalid timeout. Use -1 for no timeout, 0 for immediate timeout and a positive number " +
                                                      "of milliseconds to indicate a timeout. All other values are out of range."
                                                      );
            }

            var startTime = _timeProvider.GetUtcNow();

            while (true)
            {
                if (TryConsume(tokens))
                {
                    break;
                }

                if (timeout != Timeout.Infinite)
                {
                    // determine if the requested timeout has elapsed
                    var currentTime         = _timeProvider.GetUtcNow();
                    var elapsedMilliseconds = (currentTime - startTime).TotalMilliseconds;
                    if (elapsedMilliseconds > timeout)
                    {
                        throw new TimeoutException("The operation timed out while waiting for the rate limit to be lifted.");
                    }
                }

                _sleep.Sleep();
            }
        }
コード例 #2
0
        /// <summary>
        /// Consumes multiple tokens from the bucket.  If enough tokens are not currently available then this method will block
        /// </summary>
        /// <param name="numTokens">The number of tokens to consume from the bucket, must be a positive number.</param>
        public void Consume(long numTokens)
        {
            while (true)
            {
                if (TryConsume(numTokens))
                {
                    break;
                }

                _sleepStrategy.Sleep();
            }
        }
コード例 #3
0
        /// <summary>
        /// Consume multiple tokens from the bucket asynchronously. This method does not block
        /// <param name="numTokens">The number of tokens to consume from the bucket, must be a positive number.</param>
        /// <returns>A task that returns once the requested tokens have been consumed</returns>
        /// </summary>
        public async Task Consume(long numTokens, CancellationToken cancellationToken = default(CancellationToken))
        {
            while (true)
            {
                if (await TryConsume(numTokens).ConfigureAwait(false))
                {
                    break;
                }

                await _sleepStrategy.Sleep(cancellationToken).ConfigureAwait(false);

                cancellationToken.ThrowIfCancellationRequested();
            }
        }