private async Task UpdateTaskAsync()
        {
            try
            {
                var response = await _featureFlagRequestor.FeatureFlagsAsync();

                if (response.statusCode == 200)
                {
                    var flagsAsJsonString = response.jsonResponse;
                    var flagsDictionary   = JsonUtil.DecodeJson <ImmutableDictionary <string, FeatureFlag> >(flagsAsJsonString);
                    _flagCacheManager.CacheFlagsFromService(flagsDictionary, _user);

                    // We can't use bool in CompareExchange because it is not a reference type.
                    if (Interlocked.CompareExchange(ref _initialized, INITIALIZED, UNINITIALIZED) == UNINITIALIZED)
                    {
                        _startTask.SetResult(true);
                        Log.Info("Initialized LaunchDarkly Polling Processor.");
                    }
                }
            }
            catch (UnsuccessfulResponseException ex) when(ex.StatusCode == 401)
            {
                Log.ErrorFormat("Error Updating features: '{0}'", Util.ExceptionMessage(ex));
                Log.Error("Received 401 error, no further polling requests will be made since SDK key is invalid");
                if (_initialized == UNINITIALIZED)
                {
                    _startTask.SetException(ex);
                }
                ((IDisposable)this).Dispose();
            }
            catch (Exception ex)
            {
                Log.ErrorFormat("Error Updating features: '{0}'", Util.ExceptionMessage(PlatformSpecific.Http.TranslateHttpException(ex)));
            }
        }
示例#2
0
        private async Task UpdateTaskAsync()
        {
            try
            {
                var response = await _featureFlagRequestor.FeatureFlagsAsync();

                if (response.statusCode == 200)
                {
                    var flagsAsJsonString = response.jsonResponse;
                    var allData           = DataModelSerialization.DeserializeV1Schema(flagsAsJsonString);
                    _updateSink.Init(_user, allData);

                    if (_initialized.GetAndSet(true) == false)
                    {
                        _startTask.SetResult(true);
                        _log.Info("Initialized LaunchDarkly Polling Processor.");
                    }
                }
            }
            catch (UnsuccessfulResponseException ex)
            {
                var errorInfo = DataSourceStatus.ErrorInfo.FromHttpError(ex.StatusCode);

                if (HttpErrors.IsRecoverable(ex.StatusCode))
                {
                    _log.Warn(HttpErrors.ErrorMessage(ex.StatusCode, "polling request", "will retry"));
                    _updateSink.UpdateStatus(DataSourceState.Interrupted, errorInfo);
                }
                else
                {
                    _log.Error(HttpErrors.ErrorMessage(ex.StatusCode, "polling request", ""));
                    _updateSink.UpdateStatus(DataSourceState.Shutdown, errorInfo);

                    // if client is initializing, make it stop waiting
                    _startTask.TrySetResult(false);

                    ((IDisposable)this).Dispose();
                }
            }
            catch (JsonReadException ex)
            {
                _log.Error("Polling request received malformed data: {0}", LogValues.ExceptionSummary(ex));
                _updateSink.UpdateStatus(DataSourceState.Interrupted,
                                         new DataSourceStatus.ErrorInfo
                {
                    Kind = DataSourceStatus.ErrorKind.InvalidData,
                    Time = DateTime.Now
                });
            }
            catch (Exception ex)
            {
                Exception realEx = (ex is AggregateException ae) ? ae.Flatten() : ex;
                _log.Warn("Polling for feature flag updates failed: {0}", LogValues.ExceptionSummary(realEx));
                _log.Debug(LogValues.ExceptionTrace(realEx));
                _updateSink.UpdateStatus(DataSourceState.Interrupted,
                                         DataSourceStatus.ErrorInfo.FromException(realEx));
            }
        }
示例#3
0
        void HandleMessage(string messageType, string messageData)
        {
            _log.Debug("Event '{0}': {1}", messageType, messageData);
            switch (messageType)
            {
            case Constants.PUT:
            {
                var allData = DataModelSerialization.DeserializeV1Schema(messageData);
                _updateSink.Init(_user, allData);
                if (!_initialized.GetAndSet(true))
                {
                    _initTask.SetResult(true);
                }
                break;
            }

            case Constants.PATCH:
            {
                try
                {
                    var parsed      = LdValue.Parse(messageData);
                    var flagkey     = parsed.Get(Constants.KEY).AsString;
                    var featureFlag = DataModelSerialization.DeserializeFlag(messageData);
                    _updateSink.Upsert(_user, flagkey, featureFlag.ToItemDescriptor());
                }
                catch (Exception ex)
                {
                    LogHelpers.LogException(_log, "Error parsing PATCH message", ex);
                    _log.Debug("Message data follows: {0}", messageData);
                }
                break;
            }

            case Constants.DELETE:
            {
                try
                {
                    var    parsed      = LdValue.Parse(messageData);
                    int    version     = parsed.Get(Constants.VERSION).AsInt;
                    string flagKey     = parsed.Get(Constants.KEY).AsString;
                    var    deletedItem = new ItemDescriptor(version, null);
                    _updateSink.Upsert(_user, flagKey, deletedItem);
                }
                catch (Exception ex)
                {
                    LogHelpers.LogException(_log, "Error parsing DELETE message", ex);
                    _log.Debug("Message data follows: {0}", messageData);
                }
                break;
            }

            case Constants.PING:
            {
                Task.Run(async() =>
                    {
                        try
                        {
                            var response          = await _requestor.FeatureFlagsAsync();
                            var flagsAsJsonString = response.jsonResponse;
                            var allData           = DataModelSerialization.DeserializeV1Schema(flagsAsJsonString);
                            _updateSink.Init(_user, allData);
                            if (!_initialized.GetAndSet(true))
                            {
                                _initTask.SetResult(true);
                            }
                        }
                        catch (Exception ex)
                        {
                            LogHelpers.LogException(_log, "Error in handling PING message", ex);
                        }
                    });
                break;
            }

            default:
                break;
            }
        }