コード例 #1
0
        private async Task LoadKeyValuesRegisteredForRefresh(IDictionary <string, ConfigurationSetting> data)
        {
            _watchedSettings.Clear();

            foreach (KeyValueWatcher changeWatcher in _options.ChangeWatchers)
            {
                string             watchedKey      = changeWatcher.Key;
                string             watchedLabel    = changeWatcher.Label;
                KeyValueIdentifier watchedKeyLabel = new KeyValueIdentifier(watchedKey, watchedLabel);

                // Skip the loading for the key-value in case it has already been loaded
                if (data.TryGetValue(watchedKey, out ConfigurationSetting loadedKv) &&
                    watchedKeyLabel.Equals(new KeyValueIdentifier(loadedKv.Key, loadedKv.Label)))
                {
                    _watchedSettings[watchedKeyLabel] = loadedKv;
                    continue;
                }

                // Send a request to retrieve key-value since it may be either not loaded or loaded with a different label or different casing
                ConfigurationSetting watchedKv = null;
                try
                {
                    await CallWithRequestTracing(async() => watchedKv = await _client.GetConfigurationSettingAsync(watchedKey, watchedLabel, CancellationToken.None)).ConfigureAwait(false);
                }
                catch (RequestFailedException e) when(e.Status == (int)HttpStatusCode.NotFound)
                {
                    watchedKv = null;
                }

                // If the key-value was found, store it for updating the settings
                if (watchedKv != null)
                {
                    data[watchedKey] = watchedKv;
                    _watchedSettings[watchedKeyLabel] = watchedKv;
                }
            }
        }
コード例 #2
0
        private async Task RefreshIndividualKeyValues()
        {
            bool shouldRefreshAll = false;

            foreach (KeyValueWatcher changeWatcher in _options.ChangeWatchers)
            {
                string watchedKey   = changeWatcher.Key;
                string watchedLabel = changeWatcher.Label;

                // Skip the refresh for this key if the cached value has not expired or a refresh operation is in progress
                if (DateTimeOffset.UtcNow < changeWatcher.CacheExpires || !changeWatcher.Semaphore.Wait(0))
                {
                    continue;
                }

                try
                {
                    bool hasChanged = false;
                    KeyValueIdentifier watchedKeyLabel = new KeyValueIdentifier(watchedKey, watchedLabel);

                    if (_watchedSettings.TryGetValue(watchedKeyLabel, out ConfigurationSetting watchedKv))
                    {
                        KeyValueChange keyValueChange = default;
                        await TracingUtils.CallWithRequestTracing(_requestTracingEnabled, RequestType.Watch, _hostType,
                                                                  async() => keyValueChange = await _client.GetKeyValueChange(watchedKv, CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false);

                        changeWatcher.CacheExpires = DateTimeOffset.UtcNow.Add(changeWatcher.CacheExpirationInterval);

                        // Check if a change has been detected in the key-value registered for refresh
                        if (keyValueChange.ChangeType != KeyValueChangeType.None)
                        {
                            if (changeWatcher.RefreshAll)
                            {
                                shouldRefreshAll = true;
                                break;
                            }

                            if (keyValueChange.ChangeType == KeyValueChangeType.Deleted)
                            {
                                _watchedSettings.TryRemove(watchedKeyLabel, out ConfigurationSetting _);
                            }
                            else if (keyValueChange.ChangeType == KeyValueChangeType.Modified)
                            {
                                _watchedSettings[watchedKeyLabel] = keyValueChange.Current;
                            }

                            hasChanged = true;
                            ProcessChanges(Enumerable.Repeat(keyValueChange, 1));
                        }
                    }
                    else
                    {
                        // Load the key-value in case the previous load attempts had failed
                        var options = new SettingSelector {
                            LabelFilter = watchedLabel
                        };

                        try
                        {
                            await CallWithRequestTracing(async() => watchedKv = await _client.GetConfigurationSettingAsync(watchedKey, watchedLabel, CancellationToken.None).ConfigureAwait(false)).ConfigureAwait(false);
                        }
                        catch (RequestFailedException e) when(e.Status == (int)HttpStatusCode.NotFound)
                        {
                            watchedKv = null;
                        }

                        changeWatcher.CacheExpires = DateTimeOffset.UtcNow.Add(changeWatcher.CacheExpirationInterval);

                        if (watchedKv != null)
                        {
                            if (changeWatcher.RefreshAll)
                            {
                                shouldRefreshAll = true;
                                break;
                            }

                            hasChanged = true;

                            // Add the key-value if it is not loaded, or update it if it was loaded with a different label
                            _applicationSettings[watchedKey]  = watchedKv;
                            _watchedSettings[watchedKeyLabel] = watchedKv;
                        }
                    }

                    if (hasChanged)
                    {
                        await SetData(_applicationSettings).ConfigureAwait(false);
                    }
                }
                finally
                {
                    changeWatcher.Semaphore.Release();
                }
            }

            // Trigger a single refresh-all operation if a change was detected in one or more key-values with refreshAll: true
            if (shouldRefreshAll)
            {
                await LoadAll(ignoreFailures : false).ConfigureAwait(false);
            }
        }