Both me and my colleague were tasked with finding the connection-retry logic for Azure Table Storage. After some searching, I found this cool Enterprise Library package that contains the Microsoft.Practices.TransientFaultHandling namespace.
Following a few code examples, I finished creating the Incremental repetition strategy and wrapped one of our memory calls with the retryPolicy ExecuteAction retryPolicy ExecuteAction :
/// <inheritdoc /> public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value) { // Define your retry strategy: retry 5 times, starting 1 second apart, adding 2 seconds to the interval each retry. var retryStrategy = new Incremental(5, TimeSpan.FromSeconds(1), TimeSpan.FromSeconds(2)); var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName)); try { retryPolicy.ExecuteAction(() => { var tableClient = storageAccount.CreateCloudTableClient(); var table = tableClient.GetTableReference(SettingsTableName); table.CreateIfNotExists(); var entity = new Models.Azure.Setting { PartitionKey = GetPartitionKey(userId, bookId), RowKey = GetRowKey(settingId, itemId), UserId = userId, BookId = bookId.ToLowerInvariant(), SettingId = settingId.ToLowerInvariant(), ItemId = itemId.ToLowerInvariant(), Value = value.ToString(Formatting.None) }; table.Execute(TableOperation.InsertOrReplace(entity)); }); } catch (StorageException exception) { ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception); throw; } } }
Feeling amazing, I went to show my colleague, and he complacently noted that we can do the same without turning on the Enterprise Library, because the CloudTableClient object already has a tool for the retry policy. His code looked like this:
/// <inheritdoc /> public void SaveSetting(int userId, string bookId, string settingId, string itemId, JObject value) { var storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting(StorageConnectionStringName)); var tableClient = storageAccount.CreateCloudTableClient(); // set retry for the connection tableClient.RetryPolicy = new ExponentialRetry(TimeSpan.FromSeconds(2), 3); var table = tableClient.GetTableReference(SettingsTableName); table.CreateIfNotExists(); var entity = new Models.Azure.Setting { PartitionKey = GetPartitionKey(userId, bookId), RowKey = GetRowKey(settingId, itemId), UserId = userId, BookId = bookId.ToLowerInvariant(), SettingId = settingId.ToLowerInvariant(), ItemId = itemId.ToLowerInvariant(), Value = value.ToString(Formatting.None) }; try { table.Execute(TableOperation.InsertOrReplace(entity)); } catch (StorageException exception) { ExceptionHelpers.CheckForPropertyValueTooLargeMessage(exception); throw; } }
My question is:
Is there any significant difference between the two approaches besides their implementation? Both of them seem to achieve the same goal, but are there any cases when it is better to use one over the other?