/// <summary>A helper test for testing the <c>GetNextBackOff</c> logic.</summary> private void SubtestGetNextBackOff_MaxNumRetries(int max) { ExponentialBackOff backOff = new ExponentialBackOff(TimeSpan.Zero, max); for (int i = 1; i <= 10; ++i) { if (i <= max) { Assert.NotEqual(TimeSpan.MinValue, backOff.GetNextBackOff(i)); } else { Assert.Equal(TimeSpan.MinValue, backOff.GetNextBackOff(i)); } } }
public async static Task <Stream> ExecuteAsStreamWithRetryAsync <TResponse>( this ClientServiceRequest <TResponse> request, ExponentialBackOff backOff) { int retries = 0; while (true) { try { return(await request.ExecuteAsStreamAsync()); } catch (GoogleApiException e) when(e.Error != null && e.Error.Code == 429) { // Too many requests. if (retries < backOff.MaxNumOfRetries) { TraceSources.Common.TraceWarning( "Too many requests - backing of and retrying...", retries); retries++; await Task.Delay(backOff.GetNextBackOff(retries)); } else { // Retried too often already. TraceSources.Common.TraceWarning("Giving up after {0} retries", retries); throw; } } } }
public void GetNextBackOff_InvalidValue() { ExponentialBackOff backOff = new ExponentialBackOff(); try { backOff.GetNextBackOff(0); Assert.True(false, "Exception expected"); } catch (ArgumentOutOfRangeException) { } try { backOff.GetNextBackOff(-2); Assert.True(false, "Exception expected"); } catch (ArgumentOutOfRangeException) { } }
/// <summary> /// Waits for a report file to generate by polling for its status using exponential backoff. In the worst case, /// there will be 10 attempts to determine if the report is no longer processing. /// </summary> /// <param name="service">DfaReporting service object used to run the requests.</param> /// <param name="userProfileId">The ID number of the DFA user profile to run this request as.</param> /// <param name="file">The report file to poll the status of.</param> /// <returns>The report file object, either once it is no longer processing or /// once too much time has passed.</returns> private static File WaitForReportRunCompletion(DfareportingService service, long userProfileId, File file) { ExponentialBackOff backOff = new ExponentialBackOff(); TimeSpan interval; file = service.Reports.Files.Get(userProfileId, file.ReportId.Value, file.Id.Value).Execute(); for (int i = 1; i <= backOff.MaxNumOfRetries; i++) { if (!file.Status.Equals("PROCESSING")) { break; } interval = backOff.GetNextBackOff(i); Console.WriteLine("Polling again in {0} seconds.", interval); Thread.Sleep(interval); file = service.Reports.Files.Get(userProfileId, file.ReportId.Value, file.Id.Value).Execute(); } return(file); }
/// <summary>Test helper for testing retrying using exponential back-off.</summary> /// <param name="retry">Index of current retry.</param> /// <param name="delta">The delta the exponential back-off uses. /// <seealso cref="ExponentialBackOff.DeltaBackOff"/> for more details. /// </param> /// <param name="epsilon">Used for checking the average result of the input retry [In milliseconds].</param> private void SubtestGetNextBackOff(int retry, Nullable <TimeSpan> delta = null, int epsilon = 20) { int expectedMillis = (int)Math.Pow(2, (retry - 1)) * 1000; ExponentialBackOff backOff = delta.HasValue ? new ExponentialBackOff(delta.Value) : new ExponentialBackOff(); TimeSpan min = TimeSpan.FromMilliseconds(expectedMillis - backOff.DeltaBackOff.TotalMilliseconds); TimeSpan max = TimeSpan.FromMilliseconds(expectedMillis + backOff.DeltaBackOff.TotalMilliseconds); long total = 0; long repeat = 1000; for (int i = 0; i < repeat; ++i) { var ts = backOff.GetNextBackOff(retry); Assert.InRange(ts, min, max); total += (int)ts.TotalMilliseconds; } var average = (int)(total / repeat); Assert.InRange(average, expectedMillis - epsilon, expectedMillis + epsilon); }
public TimeSpan GetNextBackOff(int currentRetry) { RetryCount = currentRetry; return(backoff.GetNextBackOff(currentRetry)); }