Microsoft.Azure.Cosmos/src/RetryOptions.cs (114 lines of code) (raw):
//------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------
namespace Microsoft.Azure.Cosmos
{
using System;
using Microsoft.Azure.Documents;
/// <summary>
/// RetryOptions class defines the parameters an application can set to customize the
/// built-in retry policies in the Azure Cosmos DB service.
/// </summary>
/// <remarks>
/// The <see cref="DocumentClient"/> class supports retry
/// on certain types of exceptions. This class provides options for applications to control the
/// retry behavior.
/// </remarks>
internal class RetryOptions
{
internal const int DefaultMaxRetryWaitTimeInSeconds = 30;
internal const int DefaultMaxRetryAttemptsOnThrottledRequests = 9;
private readonly RetryWithConfiguration retryWithConfiguration;
private int maxRetryAttemptsOnThrottledRequests;
private int maxRetryWaitTime;
/// <summary>
/// Creates a new instance of the RetryOptions class and intialize all properties
/// to default values for the Azure Cosmos DB service.
/// </summary>
public RetryOptions()
{
this.maxRetryAttemptsOnThrottledRequests = RetryOptions.DefaultMaxRetryAttemptsOnThrottledRequests;
this.maxRetryWaitTime = RetryOptions.DefaultMaxRetryWaitTimeInSeconds;
this.retryWithConfiguration = new RetryWithConfiguration();
}
/// <summary>
/// Gets or sets the maximum number of retries in the case where the request fails
/// because the Azure Cosmos DB service has applied rate limiting on the client.
/// </summary>
/// <value>
/// The default value is 9. This means in the case where the request is rate limited,
/// the same request will be issued for a maximum of 10 times to the server before
/// an error is returned to the application. If the value of this property is set to 0,
/// there will be no automatic retry on rate limiting requests from the client and the exception
/// needs to handled at the application level.
/// For an example on how to set this value, please refer to <see cref="ConnectionPolicy.RetryOptions"/>.
/// </value>
/// <remarks>
/// <para>
/// When a client is sending requests faster than the allowed rate,
/// the service will return HttpStatusCode 429 (Too Many Request) to rate limit the client. The current
/// implementation in the SDK will then wait for the amount of time the service tells it to wait and
/// retry after the time has elapsed.
/// </para>
/// <para>
/// For more information, see <see href="https://learn.microsoft.com/azure/cosmos-db/nosql/performance-tips-dotnet-sdk-v3#429">Handle rate limiting/request rate too large</see>.
/// </para>
/// </remarks>
public int MaxRetryAttemptsOnThrottledRequests
{
get
{
return this.maxRetryAttemptsOnThrottledRequests;
}
set
{
if (value < 0)
{
throw new ArgumentException("value must be a positive integer.");
}
this.maxRetryAttemptsOnThrottledRequests = value;
}
}
/// <summary>
/// Gets or sets the maximum retry time in seconds for the Azure Cosmos DB service.
/// </summary>
/// <value>
/// The default value is 30 seconds. For an example on how to set this value, please refer to <see cref="ConnectionPolicy.RetryOptions"/>.
/// </value>
/// <remarks>
/// <para>
/// When a request fails due to a rate limiting error, the service sends back a response that
/// contains a value indicating the client should not retry before the <see cref="Microsoft.Azure.Documents.DocumentClientException.RetryAfter"/> time period has
/// elapsed. This property allows the application to set a maximum wait time for all retry attempts.
/// If the cumulative wait time exceeds the this value, the client will stop retrying and return the error to the application.
/// </para>
/// <para>
/// For more information, see <see href="https://learn.microsoft.com/azure/cosmos-db/nosql/performance-tips-dotnet-sdk-v3#429">Handle rate limiting/request rate too large</see>.
/// </para>
/// </remarks>
public int MaxRetryWaitTimeInSeconds
{
get
{
return this.maxRetryWaitTime;
}
set
{
if (value < 0 || value > int.MaxValue / 1000)
{
throw new ArgumentException("value must be a positive integer between the range of 0 to " + (int.MaxValue / 1000));
}
this.maxRetryWaitTime = value;
}
}
/// <summary>
/// Gets or sets the initial delay retry time in milliseconds for the Azure Cosmos DB service
/// for requests that hit RetryWithExceptions. This covers errors that occur due to concurrency errors in the store.
/// </summary>
/// <value>
/// The default value is 1 second. For an example on how to set this value, please refer to <see cref="ConnectionPolicy.RetryOptions"/>.
/// </value>
/// <remarks>
/// <para>
/// When a request fails due to a RetryWith error, the client delays and retries the request. This configures the client
/// to delay the time specified before retrying the request.
/// </para>
/// </remarks>
internal int? InitialRetryForRetryWithMilliseconds
{
get
{
return this.retryWithConfiguration.InitialRetryIntervalMilliseconds;
}
set
{
if (value != null && (value < 0 || value > int.MaxValue / 1000))
{
throw new ArgumentException("value must be a positive integer between the range of 0 to " + (int.MaxValue / 1000));
}
this.retryWithConfiguration.InitialRetryIntervalMilliseconds = value;
}
}
/// <summary>
/// Gets or sets the maximum delay retry time in milliseconds for the Azure Cosmos DB service
/// for requests that hit RetryWithExceptions. This covers errors that occur due to concurrency errors in the store.
/// </summary>
/// <value>
/// The default value is 30 seconds. For an example on how to set this value, please refer to <see cref="ConnectionPolicy.RetryOptions"/>.
/// </value>
/// <remarks>
/// <para>
/// When a request fails due to a RetryWith error, the client delays and retries the request. This configures the maximum time
/// the client should delay before failing the request.
/// </para>
/// </remarks>
internal int? MaximumRetryForRetryWithMilliseconds
{
get
{
return this.retryWithConfiguration.MaximumRetryIntervalMilliseconds;
}
set
{
if (value != null && (value < 0 || value > int.MaxValue / 1000))
{
throw new ArgumentException("value must be a positive integer between the range of 0 to " + (int.MaxValue / 1000));
}
this.retryWithConfiguration.MaximumRetryIntervalMilliseconds = value;
}
}
/// <summary>
/// Gets or sets the interval to salt retrywith retries with. This will spread the retry values from 1..n from the exponential backoff
/// subscribed.
/// </summary>
/// <value>
/// The default value is to not salt.
/// </value>
/// <remarks>
/// <para>
/// When a request fails due to a RetryWith error, the client delays and retries the request. This configures the jitter on the retry attempted.
/// </para>
/// </remarks>
internal int? RandomSaltForRetryWithMilliseconds
{
get
{
return this.retryWithConfiguration.RandomSaltMaxValueMilliseconds;
}
set
{
if (value != null && (value < 0 || value > int.MaxValue / 1000))
{
throw new ArgumentException("value must be a positive integer between the range of 0 to " + (int.MaxValue / 1000));
}
this.retryWithConfiguration.RandomSaltMaxValueMilliseconds = value;
}
}
/// <summary>
/// Gets or sets the total time to wait before failing the request for retrywith failures.
/// subscribed.
/// </summary>
/// <value>
/// The default value 30 seconds.
/// </value>
/// <remarks>
/// <para>
/// When a request fails due to a RetryWith error, the client delays and retries the request. This configures total time spent waiting on the request.
/// </para>
/// </remarks>
internal int? TotalWaitTimeForRetryWithMilliseconds
{
get
{
return this.retryWithConfiguration.TotalWaitTimeMilliseconds;
}
set
{
if (value != null && (value < 0 || value > int.MaxValue / 1000))
{
throw new ArgumentException("value must be a positive integer between the range of 0 to " + (int.MaxValue / 1000));
}
this.retryWithConfiguration.TotalWaitTimeMilliseconds = value;
}
}
internal RetryWithConfiguration GetRetryWithConfiguration()
{
return this.retryWithConfiguration;
}
}
}