Index: Src/GoogleApis.Tests/Apis/Http/ConfigurableMessageHandlerTest.cs =================================================================== --- a/Src/GoogleApis.Tests/Apis/Http/ConfigurableMessageHandlerTest.cs +++ b/Src/GoogleApis.Tests/Apis/Http/ConfigurableMessageHandlerTest.cs @@ -708,9 +708,9 @@ public void SendAsync_BackOffUnsuccessfulResponseHandler_ServiceUnavailable_Max10Hours() { var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero)) - { - MaxTimeSpan = TimeSpan.FromHours(10) - }; + { + MaxTimeSpan = TimeSpan.FromHours(10) + }; SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer); } @@ -728,7 +728,11 @@ [Test] public void SendAsync_BackOffUnsuccessfulResponseHandler_Cancel() { - var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero)); + // test back-off with maximum 30 minutes per single request + var initializer = new BackOffHandler.Initializer(new ExponentialBackOff(TimeSpan.Zero)) + { + MaxTimeSpan = TimeSpan.FromMinutes(30) + }; SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 2); SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode.ServiceUnavailable, initializer, 6); } @@ -739,7 +743,7 @@ /// parameter to the index of the request you want to cancel. /// private void SubtestSendAsync_BackOffUnsuccessfulResponseHandler(HttpStatusCode statusCode, - BackOffHandler.Initializer initializer, int cancelRequestNum = 0) + BackOffHandler.Initializer initializer, int cancelRequestNum = 0, int numTries = 10) { var handler = new UnsuccessfulResponseMessageHandler { ResponseStatusCode = statusCode }; @@ -754,7 +758,10 @@ cancellationToken = tcs.Token; } - var configurableHanlder = new ConfigurableMessageHandler(handler); + var configurableHanlder = new ConfigurableMessageHandler(handler) + { + NumTries = numTries + }; var boHandler = new MockBackOffHandler(initializer); configurableHanlder.UnsuccessfulResponseHandlers.Add(boHandler); @@ -840,7 +847,10 @@ { var content = "test-content"; var contentHandler = new ContentMessageHandler(); - var configurableHanlder = new ConfigurableMessageHandler(contentHandler); + var configurableHanlder = new ConfigurableMessageHandler(contentHandler) + { + NumTries = 10 + }; configurableHanlder.UnsuccessfulResponseHandlers.Add(new TrueUnsuccessfulResponseHandler()); using (var client = new HttpClient(configurableHanlder)) { @@ -900,10 +910,11 @@ public void NumTries_Setter() { var configurableHanlder = new ConfigurableMessageHandler(new HttpClientHandler()); + // valid values - configurableHanlder.NumTries = 5; + configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowedNumTries; + configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowedNumTries - 1; configurableHanlder.NumTries = 1; - configurableHanlder.NumTries = ConfigurableMessageHandler.MaxAllowedNumTries; // test invalid values try @@ -913,7 +924,7 @@ } catch (ArgumentOutOfRangeException ex) { - Assert.True(ex.Message.Contains("Parameter name: NumRetries")); + Assert.True(ex.Message.Contains("Parameter name: NumTries")); } try { @@ -922,7 +933,7 @@ } catch (ArgumentOutOfRangeException ex) { - Assert.True(ex.Message.Contains("Parameter name: NumRetries")); + Assert.True(ex.Message.Contains("Parameter name: NumTries")); } try { @@ -931,7 +942,7 @@ } catch (ArgumentOutOfRangeException ex) { - Assert.True(ex.Message.Contains("Parameter name: NumRetries")); + Assert.True(ex.Message.Contains("Parameter name: NumTries")); } } Index: Src/GoogleApis.Tests/Apis/Requests/ClientServiceRequestTest.cs =================================================================== --- a/Src/GoogleApis.Tests/Apis/Requests/ClientServiceRequestTest.cs +++ b/Src/GoogleApis.Tests/Apis/Requests/ClientServiceRequestTest.cs @@ -538,8 +538,9 @@ /// /// A subtest for testing execute when an exception is thrown during sending the request, with or without - /// back-off. If back-off handler is attached to the service's message handler, there are going to be several - /// retries (up to 2 minutes). + /// back-off. If back-off handler is attached to the service's message handler, there are going to be 3 tries + /// (3 is the default value of ) before the operation + /// fails. /// /// Indicates if back-off handler is attached to the service. private void SubtestExecute_ThrowException(bool backOff) @@ -550,20 +551,17 @@ HttpClientFactory = new MockHttpClientFactory(handler) }; - // by default back-off is used, so disable it in case backOff is false - if (!backOff) - { - initializer.DefaultExponentialBackOffPolicy = BaseClientService.ExponentialBackOffPolicy.None; - } + // sets the default exponential back-off policy by the input + initializer.DefaultExponentialBackOffPolicy = backOff ? + BaseClientService.ExponentialBackOffPolicy.Exception : + BaseClientService.ExponentialBackOffPolicy.None; using (var service = new MockClientService(initializer)) { var request = new TestClientServiceRequest(service, "GET", null); Assert.Throws(() => request.Execute()); - // if back-off is enabled, we use 2 minutes maximum wait time for a request, so we should make lg(120) - // + 1 calls - int calls = backOff ? (int)Math.Ceiling(Math.Log(120, 2) + 1) : 1; + int calls = backOff ? service.HttpClient.MessageHandler.NumTries : 1; Assert.That(handler.Calls, Is.EqualTo(calls)); } } @@ -588,8 +586,9 @@ /// /// A subtest for testing async execute when an exception is thrown during sending the request, with or without - /// back-off handler. If back-off handler is attached to the service's message handler, there are going to be - /// several retries (up to 2 minutes). + /// back-off handler. If back-off handler is attached to the service's message handler, there are going to be 3 + /// tries (3 is the default value of ) before the + /// operation fails. /// /// Indicates if back-off handler is attached to the service. private void SubtestExecuteAsync_ThrowException(bool backOff) @@ -600,11 +599,10 @@ HttpClientFactory = new MockHttpClientFactory(handler) }; - // by default back-off is used, so disable it in case backOff is false - if (!backOff) - { - initializer.DefaultExponentialBackOffPolicy = BaseClientService.ExponentialBackOffPolicy.None; - } + // configure the back-off behavior by the input + initializer.DefaultExponentialBackOffPolicy = backOff ? + BaseClientService.ExponentialBackOffPolicy.Exception : + BaseClientService.ExponentialBackOffPolicy.None; using (var service = new MockClientService(initializer)) { @@ -620,9 +618,7 @@ Assert.That(ex.InnerException, Is.AssignableFrom(typeof(InvalidOperationMockException))); } - // if back-off is enabled, we use 2 minutes maximum wait time for a request, so we should make lg(120) - // + 1 calls - int calls = backOff ? (int)Math.Ceiling(Math.Log(120, 2) + 1) : 1; + int calls = backOff ? service.HttpClient.MessageHandler.NumTries : 1; Assert.That(handler.Calls, Is.EqualTo(calls)); } } Index: Src/GoogleApis.Tests/Apis/Services/BaseClientServiceTest.cs =================================================================== --- a/Src/GoogleApis.Tests/Apis/Services/BaseClientServiceTest.cs +++ b/Src/GoogleApis.Tests/Apis/Services/BaseClientServiceTest.cs @@ -349,13 +349,10 @@ Assert.That(service.Authenticator, Is.EqualTo(NullAuthenticator.Instance)); Assert.True(service.GZipEnabled); - // back-off handlers are added by default + // back-off handler for unsuccessful response (503) is added by default Assert.That(service.HttpClient.MessageHandler.UnsuccessfulResponseHandlers.Count, Is.EqualTo(1)); Assert.That(service.HttpClient.MessageHandler.UnsuccessfulResponseHandlers[0], Is.InstanceOf()); - Assert.That(service.HttpClient.MessageHandler.ExceptionHandlers.Count, Is.EqualTo(1)); - Assert.That(service.HttpClient.MessageHandler.ExceptionHandlers[0], - Is.InstanceOf()); // one execute interceptor (for adding the "Authenticate" header Assert.That(service.HttpClient.MessageHandler.ExecuteInterceptors.Count, Is.EqualTo(1)); Index: Src/GoogleApis.Tests/Apis/Utils/ExponentialBackOffTest.cs =================================================================== --- a/Src/GoogleApis.Tests/Apis/Utils/ExponentialBackOffTest.cs +++ b/Src/GoogleApis.Tests/Apis/Utils/ExponentialBackOffTest.cs @@ -63,7 +63,7 @@ } - /// An helper subtest to test invalid value given to the constructor. + /// A helper subtest to test invalid value given to the constructor. private void SubtestConstructor_InvalidValue(TimeSpan ts, int max = 10) { try @@ -113,7 +113,6 @@ Assert.That(avarage, Is.InRange(expectedMiliis - epsilon, expectedMiliis + epsilon)); } - /// Tests next back-off time span with specific maximum of retries. [Test] public void GetNextBackOff_MaxNumRetries() @@ -123,7 +122,8 @@ SubtestGetNextBackOff_MaxNumRetries(11); } - public void SubtestGetNextBackOff_MaxNumRetries(int max) + /// A helper test for testing the GetNextBackOff logic. + private void SubtestGetNextBackOff_MaxNumRetries(int max) { ExponentialBackOff backOff = new ExponentialBackOff(TimeSpan.Zero, max); Index: Src/GoogleApis/Apis/Authentication/DelegateAuthenticator.cs =================================================================== --- a/Src/GoogleApis/Apis/Authentication/DelegateAuthenticator.cs +++ b/Src/GoogleApis/Apis/Authentication/DelegateAuthenticator.cs @@ -35,7 +35,7 @@ /// /// The request needing authentication. public delegate void RequestModifier(HttpWebRequest webRequest); - + /// /// Creates a new DelegateAuthenticator. /// @@ -50,7 +50,7 @@ /// Apply authentication to the request. Calls the RequestModifier delegate /// modify the request by adding authentication information. /// - /// The request needing authentication. + /// The request needing authentication. public virtual void ApplyAuthenticationToRequest(HttpWebRequest request) { modifyRequestDelegate(request); Index: Src/GoogleApis/Apis/Http/BackOffHandler.cs =================================================================== --- a/Src/GoogleApis/Apis/Http/BackOffHandler.cs +++ b/Src/GoogleApis/Apis/Http/BackOffHandler.cs @@ -40,7 +40,7 @@ /// /// Gets or sets the maximum time span to wait. If the back-off instance returns a greater time span then /// this value, this handler returns false to both and - /// . Default value is 2 minutes per a retry request. + /// . Default value is 5 seconds per a retry request. /// public TimeSpan MaxTimeSpan { get; set; } @@ -56,9 +56,9 @@ /// public Func HandleExceptionFunc { get; set; } - /// Default function which handles server errors (5xx). + /// Default function which handles server errors (503). public static readonly Func DefaultHandleUnsuccessfulResponseFunc = - (r) => (int)r.StatusCode / 100 == 5; + (r) => (int)r.StatusCode == 503; /// /// Default function which handles exception which aren't @@ -75,7 +75,7 @@ BackOff = backOff; HandleExceptionFunc = DefaultHandleExceptionFunc; HandleUnsuccessfulResponseFunc = DefaultHandleUnsuccessfulResponseFunc; - MaxTimeSpan = TimeSpan.FromMinutes(2); + MaxTimeSpan = TimeSpan.FromSeconds(5); } } @@ -84,7 +84,7 @@ /// /// Gets the maximum time span to wait. If the back-off instance returns a greater time span, the handle method - /// returns false. Default value is 2 minutes per a retry request. + /// returns false. Default value is 5 seconds per a retry request. /// public TimeSpan MaxTimeSpan { get; private set; } Index: Src/GoogleApis/Apis/Http/ConfigurableMessageHandler.cs =================================================================== --- a/Src/GoogleApis/Apis/Http/ConfigurableMessageHandler.cs +++ b/Src/GoogleApis/Apis/Http/ConfigurableMessageHandler.cs @@ -84,14 +84,14 @@ #endregion - /// Number of tries. Default is 10. - private int numTries = 10; + /// Number of tries. Default is 3. + private int numTries = 3; /// /// Gets or sets the number of tries that will be allowed to execute. Retries occur as a result of either /// or which handles the /// abnormal Http response or exception, before being terminated. - /// Set 1 for not retrying requests. The default value is 10". + /// Set 1 for not retrying requests. The default value is 3". /// public int NumTries { @@ -100,7 +100,7 @@ { if (value > MaxAllowedNumTries || value < 1) { - throw new ArgumentOutOfRangeException("NumRetries"); + throw new ArgumentOutOfRangeException("NumTries"); } numTries = value; } Index: Src/GoogleApis/Apis/Services/BaseClientService.cs =================================================================== --- a/Src/GoogleApis/Apis/Services/BaseClientService.cs +++ b/Src/GoogleApis/Apis/Services/BaseClientService.cs @@ -54,7 +54,7 @@ #region Initializer /// - /// Indicates if exponential back-off is used automatically on exception in a service request and\or when 5xx + /// Indicates if exponential back-off is used automatically on exception in a service request and\or when 503 /// response is returned form the server. /// [Flags] @@ -62,7 +62,7 @@ { None = 0, Exception = 1, - UnsuccessfulResponse5xx = 2 + UnsuccessfulResponse503 = 2 } /// An initializer class for the client service. @@ -82,9 +82,9 @@ public IConfigurableHttpClientInitializer HttpClientInitializer { get; set; } /// - /// Gets or sets the exponential back-off policy used by the service. Default value is Exception | - /// UnsuccessfulResponse5xx, which means that exponential back-off is used on any 5xx abnormal Http - /// response and on any exception whose thrown when sending a request (except task canceled exception). + /// Get or sets the exponential back-off policy used by the service. Default value is + /// UnsuccessfulResponse503, which means that exponential back-off is used on 503 abnormal HTTP + /// response. /// If the value is set to None, no exponential back-off policy is used, and it's up to user to /// configure the in an /// to set a specific back-off @@ -120,8 +120,7 @@ GZipEnabled = true; Serializer = new NewtonsoftJsonSerializer(); Authenticator = NullAuthenticator.Instance; - DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.Exception | - ExponentialBackOffPolicy.UnsuccessfulResponse5xx; + DefaultExponentialBackOffPolicy = ExponentialBackOffPolicy.UnsuccessfulResponse503; } } @@ -153,8 +152,8 @@ httpClient.MessageHandler.ExceptionHandlers.Add(backOff); } - if ((Policy & ExponentialBackOffPolicy.UnsuccessfulResponse5xx) == - ExponentialBackOffPolicy.UnsuccessfulResponse5xx) + if ((Policy & ExponentialBackOffPolicy.UnsuccessfulResponse503) == + ExponentialBackOffPolicy.UnsuccessfulResponse503) { httpClient.MessageHandler.UnsuccessfulResponseHandlers.Add(backOff); } @@ -182,9 +181,7 @@ HttpClient = CreateHttpClient(initializer); } - /// - /// Return true if this service contains the specified feature. - /// + /// Return true if this service contains the specified feature. private bool HasFeature(Features feature) { return Features.Contains(feature.GetStringValue()); Index: Src/GoogleApis/Apis/[Media]/Download/MediaDownloader.cs =================================================================== --- a/Src/GoogleApis/Apis/[Media]/Download/MediaDownloader.cs +++ b/Src/GoogleApis/Apis/[Media]/Download/MediaDownloader.cs @@ -78,7 +78,7 @@ /// Constructs a new progress instance. /// An exception which occurred during the download. - /// The number of bytes received before the exception occurred. + /// The number of bytes received before the exception occurred. public DownloadProgress(Exception exception, long bytes) { Status = DownloadStatus.Failed; Index: Src/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs =================================================================== --- a/Src/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs +++ b/Src/GoogleApis/Apis/[Media]/Upload/ResumableUpload.cs @@ -125,7 +125,8 @@ public IClientService Service { get; private set; } /// - /// Gets or sets the path of the method (combined with ) to produce absolute Uri. + /// Gets or sets the path of the method (combined with ) to produce + /// absolute Uri. /// public string Path { get; private set; }