Reputation: 8993
I use following code:
Create a retry policy, when error, retry after 1 second, then wait 3 seconds, then 5 seconds. based on Azure SLA, retry within 10 seconds must success (No throttled, I sure this. because error even happens on unique partition and table which no traffic yet)
var retryStrategy = new Incremental(3, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2));
var FaultHandlingRetryPolicy = new RetryPolicy<StorageTransientErrorDetectionStrategy>(retryStrategy);
Then I use this code to get data
FaultHandlingRetryPolicy .ExecuteAction(() =>
{
var results = (from q in Query select new q).ToList();
});
I DO NOT KNOW if its retried or not, because the error log not shown
Errors:
System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it 70.37.127.112:443
at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.GetResponse()
at System.Data.Services.Client.QueryResult.Execute()
at System.Data.Services.Client.DataServiceRequest.Execute[TElement](DataServiceContext context, QueryComponents queryComponents)
at System.Data.Services.Client.DataServiceQuery`1.Execute()
at System.Data.Services.Client.DataServiceQuery`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.<>c__DisplayClass1.<ExecuteAction>b__0()
at Microsoft.Practices.TransientFaultHandling.RetryPolicy.ExecuteAction[TResult](Func`1 func)
Please let me know if this code will retry, thanks
Upvotes: 1
Views: 4066
Reputation: 10291
When you setup a retry policy, you specify the class that will control the retires, in your case it is StorageTransientErrorDetectionStrategy
.
Each time an exception is thrown inside the ExecuteAction()
method, this class will decide if a retry is possible or not. For instance some exceptions are transient, so it's not worth retrying them.
To actually track the number of retries, you can use code like this:
FaultHandlingRetryPolicy.Retrying += (obj, eventArgs) =>
{
Console.Writeline("Retrying, CurrentRetryCount = {0} , Exception = {1}", eventArgs.CurrentRetryCount, eventArgs.LastException.Message);
};
Update
You can create your own error handling strategy like so and use it in-place of the standard one. BUT you'll have to tune the errors to fit with your scenario, these worked for me.
public class CustomSqlAzureTransientErrorDetectionStrategy : ITransientErrorDetectionStrategy
{
private readonly SqlAzureTransientErrorDetectionStrategy _normalStrategy =
new SqlAzureTransientErrorDetectionStrategy();
public bool IsTransient(Exception ex)
{
if (_normalStrategy.IsTransient(ex))
return true;
//do our custom logic
if (ex is SqlException)
{
var sqEx = ex as SqlException;
if (sqEx.Message.Contains("The timeout period elapsed prior to completion of the operation or the server is not responding") ||
sqEx.Message.Contains("An existing connection was forcibly closed by the remote host") ||
sqEx.Message.Contains("The service has encountered an error processing your request. Please try again") ||
sqEx.Message.Contains("Timeout expired") ||
sqEx.Message.Contains("was deadlocked on lock resources with another process and has been chosen as the deadlock victim") ||
sqEx.Message.Contains("A transport-level error has occurred when receiving results from the server"))
{
return true;
}
}
return false;
}
}
Upvotes: 5