/// <summary> /// Starts a background operation to check for new Remote Settings and apply them. /// </summary> public void Start() { RequiresNotDisposed(); if (!isStarted) { if (isUpdateDisabled()) { StartTask = Task.FromResult(false); } else { List <Task <GroupedRemoteSettings> > tasks = new List <Task <GroupedRemoteSettings> >(); foreach (IRemoteSettingsProvider allRemoteSettingsProvider in AllRemoteSettingsProviders) { tasks.Add(allRemoteSettingsProvider.Start()); } StartTask = Task.Run(async delegate { await logger.Start().ConfigureAwait(false); IEnumerable <GroupedRemoteSettings> source = (await Task.WhenAll(tasks).ConfigureAwait(false)).Where((GroupedRemoteSettings x) => x != null); if ((nonScopedStorageHandler != null || logger.LoggingEnabled) && source.Any()) { GroupedRemoteSettings groupedRemoteSettings = source.Reverse().Aggregate(delegate(GroupedRemoteSettings a, GroupedRemoteSettings b) { a.Merge(b, logger); return(a); }); logger.LogVerbose("Merged settings", groupedRemoteSettings); if (nonScopedStorageHandler != null) { using (Mutex mutex = new Mutex(false, "Global\\A7B8B64E-AEB3-4053-BC8C-C187F5320352")) { try { mutex.WaitOne(-1, false); } catch (AbandonedMutexException) { } try { nonScopedStorageHandler.DeleteAllSettings(); nonScopedStorageHandler.SaveNonScopedSettings(groupedRemoteSettings); } catch { } finally { mutex.ReleaseMutex(); } } } } OnRemoteSettingsApplied(); }); } isStarted = true; } }
/// <summary> /// Merges the passed in GroupedRemoteSettings from buckets into this instance. /// Identical settings in this instance will be overwritten by those in buckets. /// </summary> /// <param name="buckets"></param> /// <param name="logger"></param> public void Merge(GroupedRemoteSettings buckets, IRemoteSettingsLogger logger) { foreach (string key in buckets.Keys) { RemoteSettingPossibilities remoteSettingPossibilities = buckets[key]; if (!TryGetValue(key, out RemoteSettingPossibilities value)) { value = (base[key] = new RemoteSettingPossibilities()); } foreach (string key2 in remoteSettingPossibilities.Keys) { List <RemoteSetting> list = remoteSettingPossibilities[key2]; if (!value.TryGetValue(key2, out List <RemoteSetting> value2)) { value2 = (value[key2] = new List <RemoteSetting>()); } for (int num = list.Count - 1; num >= 0; num--) { RemoteSetting remoteSetting = list[num]; int num2 = value2.FindIndex((RemoteSetting s) => s.Name == remoteSetting.Name && s.ScopeString == remoteSetting.ScopeString); if (num2 != -1) { logger.LogVerbose($"Overwriting RemoteSetting during merge: Old value from {value2[num2]}"); logger.LogVerbose($"Overwriting RemoteSetting during merge: New value from {remoteSetting}"); value2[num2] = remoteSetting; } else { value2.Insert(0, remoteSetting); } } } } }
private void SaveSettingsInternal(string newCollectionPath, GroupedRemoteSettings groupedSettings) { foreach (KeyValuePair <string, RemoteSettingPossibilities> groupedSetting in groupedSettings) { string text = Path.Combine(newCollectionPath, groupedSetting.Key); foreach (KeyValuePair <string, List <RemoteSetting> > item in groupedSetting.Value) { bool flag = false; string text2 = text; if (item.Value.Count > 1 || item.Value[0].HasScope) { flag = true; text2 = Path.Combine(text2, item.Key + "*"); } for (int i = 0; i < item.Value.Count; i++) { RemoteSetting remoteSetting = item.Value[i]; string text3 = remoteSetting.Name; if (flag) { text3 = i.ToString() + ":" + text3; } if (remoteSetting.HasScope) { text3 = text3 + ":" + remoteSetting.ScopeString; } remoteSettingsStorage.SetValue(text2, text3, remoteSetting.Value); } } } }
private async Task <GroupedRemoteSettings> ProcessRemoteSettingsFromTargetedNotificationsAsync() { IEnumerable <LoggingContext <ActionWrapper <JObject> > > source = await GetActionsInternalAsync <JObject>("VS\\Core\\RemoteSettings", false).ConfigureAwait(false); if (source.Any()) { List <GroupedRemoteSettings> list = new List <GroupedRemoteSettings>(); List <Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> > list2 = new List <Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> >(); foreach (LoggingContext <ActionWrapper <JObject> > item in source.OrderBy((LoggingContext <ActionWrapper <JObject> > x) => x.Value.Precedence)) { DeserializedRemoteSettings deserializedRemoteSettings = remoteSettingsParser.TryParseFromJObject(item.Value.Action, string.IsNullOrEmpty(item.Value.FlightName) ? null : ("Flight." + item.Value.FlightName)); if (deserializedRemoteSettings.Successful) { list.Add(new GroupedRemoteSettings(deserializedRemoteSettings, Name + "-" + item.Context)); } else { logger.LogError("Error deserializing TN rule " + item.Context + ": " + deserializedRemoteSettings.Error); list2.Add(Tuple.Create(item.Value, deserializedRemoteSettings)); } } if (list2.Any()) { string name = "VS/Core/RemoteSettings/TargetedParseSettings"; Dictionary <string, object> dictionary = new Dictionary <string, object>(); dictionary["VS.Core.RemoteSettings.TargetedRuleIds"] = string.Join(",", list2.Select((Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> x) => x.Item1.RuleId)); dictionary["VS.Core.RemoteSettings.TargetedErrors"] = string.Join(",", list2.Select((Tuple <ActionWrapper <JObject>, DeserializedRemoteSettings> x) => x.Item2.Error)); remoteSettingsTelemetry.PostEvent(name, dictionary); } if (list.Any()) { GroupedRemoteSettings groupedRemoteSettings = list.Aggregate(delegate(GroupedRemoteSettings a, GroupedRemoteSettings b) { a.Merge(b, logger); return(a); }); liveStorageHandler.SaveSettings(groupedRemoteSettings); Interlocked.Exchange(ref currentStorageHandler, liveStorageHandler); cacheableStorageHandler.DeleteAllSettings(); cacheableStorageHandler.SaveSettings(groupedRemoteSettings); return(groupedRemoteSettings); } } else { Interlocked.Exchange(ref currentStorageHandler, liveStorageHandler); cacheableStorageHandler.DeleteAllSettings(); } return(null); }
public void SaveNonScopedSettings(GroupedRemoteSettings groupedSettings) { foreach (KeyValuePair <string, RemoteSettingPossibilities> groupedSetting in groupedSettings) { foreach (KeyValuePair <string, List <RemoteSetting> > item in groupedSetting.Value) { foreach (RemoteSetting item2 in item.Value) { if (!item2.HasScope) { remoteSettingsStorage.SetValue(item2.Path, item2.Name, item2.Value); } } } } }
public override Task <GroupedRemoteSettings> Start() { Interlocked.Exchange(ref startTask, Task.Run(async delegate { GroupedRemoteSettings result = null; queryIteration++; ActionResponseBag actionResponseBag = await GetTargetedNotificationActionsAsync().ConfigureAwait(false); if (actionResponseBag != null) { ProcessActionResponseBag(actionResponseBag); result = await ProcessRemoteSettingsFromTargetedNotificationsAsync().ConfigureAwait(false); } StartAgainAfter(serviceQueryLoopTimeSpan); return(result); })); return(startTask); }
public void SaveSettings(GroupedRemoteSettings remoteSettings) { SaveSettingsInternal(CollectionPathPrefix, remoteSettings); }