public static bool TryReadBlob <T>(CloudBlockBlob blob, out T configurationStore) where T : class { configurationStore = default(T); try { string content = blob.DownloadText(); if (content == Constants.ConfigurationStoreUpdatingText) { return(false); } string blobContent = content; configurationStore = JsonStore <T> .Deserialize(blobContent); return(true); } catch (Exception e) { ReplicatedTableLogger.LogError("Error reading blob: {0}. Exception: {1}", blob.Uri, e.Message); } return(false); }
public void UpdateConfiguration(List <ReplicaInfo> replicaChain, int readViewHeadIndex, bool convertXStoreTableMode = false) { Parallel.ForEach(this.blobs, blob => { ReplicatedTableConfigurationStore configurationStore = null; long newViewId = 0; if (!CloudBlobHelpers.TryReadBlob <ReplicatedTableConfigurationStore>(blob.Value, out configurationStore)) { //This is the first time we are uploading the config configurationStore = new ReplicatedTableConfigurationStore(); } newViewId = configurationStore.ViewId + 1; configurationStore.LeaseDuration = Constants.LeaseDurationInSec; configurationStore.Timestamp = DateTime.UtcNow; configurationStore.ReplicaChain = replicaChain; configurationStore.ReadViewHeadIndex = readViewHeadIndex; configurationStore.ConvertXStoreTableMode = convertXStoreTableMode; configurationStore.ViewId = newViewId; //If the read view head index is not 0, this means we are introducing 1 or more replicas at the head. For //each such replica, update the view id in which it was added to the write view of the chain if (readViewHeadIndex != 0) { for (int i = 0; i < readViewHeadIndex; i++) { replicaChain[i].ViewInWhichAddedToChain = newViewId; } } try { //Step 1: Delete the current configuration blob.Value.UploadText(Constants.ConfigurationStoreUpdatingText); //Step 2: Wait for L + CF to make sure no pending transaction working on old views // Chunzhi: removed this, original code hangs here // Matt: restore this: it's essential for consistency. Thread.Sleep(TimeSpan.FromSeconds(Constants.LeaseDurationInSec + Constants.ClockFactorInSec)); //Step 3: Update new config blob.Value.UploadText(JsonStore <ReplicatedTableConfigurationStore> .Serialize(configurationStore)); } catch (StorageException e) { ReplicatedTableLogger.LogError("Updating the blob: {0} failed. Exception: {1}", blob.Value, e.Message); } }); //Invalidate the lastViewRefreshTime so that updated views get returned this.lastViewRefreshTime = DateTime.MinValue; }
public static ReplicatedTableConfiguration MakeCopy(ReplicatedTableConfiguration config) { if (config == null) { return(null); } var str = config.ToJson(); return(JsonStore <ReplicatedTableConfiguration> .Deserialize(str)); }
public static ReplicatedTableConfiguration FromJson(string json) { if (string.IsNullOrEmpty(json)) { return(new ReplicatedTableConfiguration()); } var config = JsonStore <ReplicatedTableConfiguration> .Deserialize(json); config.ValidateAndFixConfig(); return(config); }
public string ToJson() { return(JsonStore <ReplicatedTableConfiguration> .Serialize(this)); }