Yes, it is possible and is done by means of the Transient Fault Handling Block. There can be multiple causes of transient failures while using the cloud environment:
- Due to the presence of more load balancers, we can see that the application to database connections fail periodically.
- While using multi-tenant services, the calls get slower and eventually time out because other applications are using resources to hit the same resource heavily.
- The last cause can be we ourselves as the user trying to hit the resource very frequently which causes the service to deliberately deny the connection to us to support other tenants in the architecture.
Instead of showing errors to the user periodically, the application can recognize the errors that are transient and automatically try to perform the same operation again typically after some seconds with the hope of establishing the connection. By making use of the Transient Fault Handling Application Block mechanism, we can generate the retry intervals and make the application perform retries. In the majority of the cases, the error would be resolved on the second try and hence the user need not be made aware of these errors unnecessarily.
Following is the sample code that can be used for the retry policy. Here, if the connection is not successful, then the action is retried based on the retry policy defined. There are 3 retry strategies - Fixed Interval, Incremental Interval, Exponential Backoff Strategy.
/***
* Class to detect Transient Blocks - Here
* OperationCancelledException is
* detected and then the retry strategy is employed.
*/
internal class AppTransientDetection : ITransientErrorDetectionStrategy
{
bool IsTransient(Exception exception) =>
exception is OperationCanceledException;
}
/***
* Retry Strategy - Here Fixed Interval Strategy is employed and is retried for 5 times.
*/
RetryStrategy retryStrategy = new FixedInterval(retryCount: 5, retryInterval: TimeSpan.FromSeconds(2));
RetryPolicy retryPolicy = new RetryPolicy(new AppTransientDetection(), retryStrategy);
retryPolicy.ExecuteAction(() => {
try {
string commandText = @”USE FEDERATION User_Federation(ShardId =” + shardId + “) WITH RESET, FILTERING=ON”;
userEntity.Connection.Open();
userEntity.ExecuteStoreCommand(commandText);
} catch (Exception e) {
userEntity.Connection.Close();
SqlConnection.ClearAllPools();
}
});