private static async Task SyncOneEntryObject( Tuple <JObject, List <int>, int, string> tuple, BlobDirectory dir, String entry, List <int> statuses) { if (!Object.ReferenceEquals(tuple.Item2, null) && tuple.Item2.Count > 0) { var dirProviders = dir.GetAllProviders(); if (Object.ReferenceEquals(statuses, null)) { statuses = dirProviders.ConvertAll(x => 0); } var content = tuple.Item1.ToString(); foreach (var i in tuple.Item2) { try { if (statuses[i] >= 0) { var item = dirProviders[i].GetBlockBlobReference(entry); await item.UploadTextAsync(content); Console.WriteLine($"Sync {dir.Name}/{entry} for {dirProviders[i].Provider.Name}"); statuses[i] = 1; } } catch { var provider = dirProviders[i].Provider.Name; Console.WriteLine($"Sync {entry} failed, the provider {provider} is not operational"); statuses[i] = -1; } } } }
/// <summary> /// Gets the consistent JObject, this is used for JObject that are stored at multiple cloud provider without the hash (for consistency). /// A certain key, usually time, is used to identity the freshness of the JObject, the object with the latest time is considered the latest. /// </summary> /// <returns>The consistent JObject, a list of blob that needs to be updated, current blob, and eTag (if exists) </returns> /// <param name="dir">directory.</param> /// <param name="tag">path .</param> public static async Task <Tuple <JObject, List <int>, int, string> > GetConsistentJObject(BlobDirectory dir, String entry, String timeTag = Constant.JSonKeyTime) { var allDirs = dir.GetAllProviders(); var allBlobs = allDirs.ConvertAll(x => x.GetBlockBlobReference(entry)); var allTasks = allBlobs.ConvertAll(x => x.DownloadTextAsync()); try { await Task.WhenAll(allTasks); } catch {}; List <Tuple <String, int> > curStrs = new List <Tuple <string, int> >(); for (int i = 0; i < allBlobs.Count; i++) { var task = allTasks[i]; var curBlob = allBlobs[i]; String str = null; if (task.Status == TaskStatus.RanToCompletion) { str = task.Result; } curStrs.Add(new Tuple <String, int>(str, i)); } ; // Nothing if (curStrs.Count <= 0) { return(new Tuple <JObject, List <int>, int, string>(new JObject(), null, -1, null)); } var curObjs = curStrs.ConvertAll(x => JsonUtils.TryParse(x.Item1)); var modTicks = curObjs.ConvertAll(x => JsonUtils.GetType <Int64>(timeTag, x, 0L)); // Console.WriteLine($"Consistency object {entry} ticks: {String.Join( ',', modTicks.ConvertAll(x => x.ToString()) )}"); var bestObj = LatestModified(modTicks); if (bestObj < 0) { bestObj = 0; } var retObj = curObjs[bestObj]; var retIdx = curStrs[bestObj].Item2; var eTag = allBlobs[retIdx].ETag; var lst = new List <int>(); for (int i = 0; i < modTicks.Count; i++) { if (modTicks[i] < modTicks[bestObj]) { lst.Add(curStrs[i].Item2); } } if (lst.Count <= 0) { lst = null; } return(new Tuple <JObject, List <int>, int, string>(retObj, lst, retIdx, eTag)); }