private async Task <TResult> TryExecuteAsync <TResult>(Func <Task <TResult> > funcToThrottle) { await this.WaitIfNeededAsync(); var result = await funcToThrottle(); TrueShipLogger.Log().Debug("Throttler: request executed successfully"); this.SubtractQuota(); return(result); }
private async void SubtractQuota() { await this.semaphore.WaitAsync(); try { this._remainingQuota--; if (this._remainingQuota < 0) { this._remainingQuota = 0; } } finally { this.semaphore.Release(); } this._requestTimer.Start(); TrueShipLogger.Log().Debug("Throttler: substracted quota, now available {0}", this._remainingQuota); }
private async Task WaitIfNeededAsync() { await this.semaphore.WaitAsync(); try { this.UpdateRequestQuoteFromTimer(); if (this._remainingQuota != 0) { return; } } finally { this.semaphore.Release(); } TrueShipLogger.Log().Debug("Throttler: quota exceeded. Waiting..."); await this._delay(); }
public async Task <TResult> ExecuteAsync <TResult>(Func <Task <TResult> > funcToThrottle) { var retryCount = 0; while (true) { var shouldWait = false; try { TrueShipLogger.Log().Debug("Throttler: trying execute request for the {0} time", retryCount); return(await this.TryExecuteAsync(funcToThrottle).ConfigureAwait(false)); } catch (Exception ex) { if (!this.IsExceptionFromThrottling(ex)) { throw; } if (retryCount >= this._maxRetryCount) { throw new ThrottlerException("Throttle max retry count reached", ex); } TrueShipLogger.Log().Debug("Throttler: got throttling exception. Retrying..."); this._remainingQuota = 0; this._requestTimer.Restart(); shouldWait = true; retryCount++; // try again through loop } if (shouldWait) { TrueShipLogger.Log().Debug("Throttler: waiting before next retry..."); await this._delay(); } } }
private void UpdateRequestQuoteFromTimer() { if (!this._requestTimer.IsRunning || this._remainingQuota == this._maxQuota) { return; } var totalSeconds = this._requestTimer.Elapsed.TotalSeconds; var elapsed = ( int )Math.Floor(totalSeconds); var quotaReleased = this._releasedQuotaCalculator(elapsed); TrueShipLogger.Log().Debug("Throttler: {0} seconds elapsed, quota released: {1}", elapsed, quotaReleased); if (quotaReleased == 0) { return; } this._remainingQuota = Math.Min(this._remainingQuota + quotaReleased, this._maxQuota); TrueShipLogger.Log().Debug("Throttler: added quota, now available {0}", this._remainingQuota); this._requestTimer.Reset(); }