Esempio n. 1
0
        private EvaluationDetail <T> Evaluate <T>(string featureKey, User user, LdValue defaultValue, LdValue.Converter <T> converter,
                                                  bool checkType, EventFactory eventFactory)
        {
            T defaultValueOfType = converter.ToType(defaultValue);

            if (!Initialized)
            {
                if (_dataStore.Initialized())
                {
                    _evalLog.Warn("Flag evaluation before client initialized; using last known values from data store");
                }
                else
                {
                    _evalLog.Warn("Flag evaluation before client initialized; data store unavailable, returning default value");
                    return(new EvaluationDetail <T>(defaultValueOfType, null,
                                                    EvaluationReason.ErrorReason(EvaluationErrorKind.ClientNotReady)));
                }
            }

            FeatureFlag featureFlag = null;

            try
            {
                featureFlag = GetFlag(featureKey);
                if (featureFlag == null)
                {
                    _evalLog.Info("Unknown feature flag \"{0}\"; returning default value",
                                  featureKey);
                    _eventProcessor.RecordEvaluationEvent(eventFactory.NewUnknownFlagEvaluationEvent(
                                                              featureKey, user, defaultValue, EvaluationErrorKind.FlagNotFound));
                    return(new EvaluationDetail <T>(defaultValueOfType, null,
                                                    EvaluationReason.ErrorReason(EvaluationErrorKind.FlagNotFound)));
                }

                if (user == null || user.Key == null)
                {
                    _evalLog.Warn("Null user or null user key when evaluating flag \"{0}\"; returning default value", featureKey);
                    _eventProcessor.RecordEvaluationEvent(eventFactory.NewDefaultValueEvaluationEvent(
                                                              featureFlag, user, defaultValue, EvaluationErrorKind.UserNotSpecified));
                    return(new EvaluationDetail <T>(defaultValueOfType, null,
                                                    EvaluationReason.ErrorReason(EvaluationErrorKind.UserNotSpecified)));
                }

                Evaluator.EvalResult evalResult = _evaluator.Evaluate(featureFlag, user, eventFactory);
                if (!IsOffline())
                {
                    foreach (var prereqEvent in evalResult.PrerequisiteEvents)
                    {
                        _eventProcessor.RecordEvaluationEvent(prereqEvent);
                    }
                }
                var evalDetail = evalResult.Result;
                EvaluationDetail <T> returnDetail;
                if (evalDetail.VariationIndex == null)
                {
                    returnDetail = new EvaluationDetail <T>(defaultValueOfType, null, evalDetail.Reason);
                    evalDetail   = new EvaluationDetail <LdValue>(defaultValue, null, evalDetail.Reason);
                }
                else
                {
                    if (checkType && !defaultValue.IsNull && evalDetail.Value.Type != defaultValue.Type)
                    {
                        _evalLog.Error("Expected type {0} but got {1} when evaluating feature flag \"{2}\"; returning default value",
                                       defaultValue.Type,
                                       evalDetail.Value.Type,
                                       featureKey);

                        _eventProcessor.RecordEvaluationEvent(eventFactory.NewDefaultValueEvaluationEvent(
                                                                  featureFlag, user, defaultValue, EvaluationErrorKind.WrongType));
                        return(new EvaluationDetail <T>(defaultValueOfType, null,
                                                        EvaluationReason.ErrorReason(EvaluationErrorKind.WrongType)));
                    }
                    returnDetail = new EvaluationDetail <T>(converter.ToType(evalDetail.Value),
                                                            evalDetail.VariationIndex, evalDetail.Reason);
                }
                _eventProcessor.RecordEvaluationEvent(eventFactory.NewEvaluationEvent(
                                                          featureFlag, user, evalDetail, defaultValue));
                return(returnDetail);
            }
            catch (Exception e)
            {
                LogHelpers.LogException(_evalLog,
                                        string.Format("Exception when evaluating feature flag \"{0}\"", featureKey),
                                        e);
                var reason = EvaluationReason.ErrorReason(EvaluationErrorKind.Exception);
                if (featureFlag == null)
                {
                    _eventProcessor.RecordEvaluationEvent(eventFactory.NewUnknownFlagEvaluationEvent(
                                                              featureKey, user, defaultValue, EvaluationErrorKind.Exception));
                }
                else
                {
                    _eventProcessor.RecordEvaluationEvent(eventFactory.NewEvaluationEvent(
                                                              featureFlag, user, new EvaluationDetail <LdValue>(defaultValue, null, reason), defaultValue));
                }
                return(new EvaluationDetail <T>(defaultValueOfType, null, reason));
            }
        }
Esempio n. 2
0
        /// <inheritdoc/>
        public FeatureFlagsState AllFlagsState(User user, params FlagsStateOption[] options)
        {
            if (IsOffline())
            {
                _evalLog.Warn("AllFlagsState() called when client is in offline mode; returning empty state");
                return(new FeatureFlagsState(false));
            }
            if (!Initialized)
            {
                if (_dataStore.Initialized())
                {
                    _evalLog.Warn("AllFlagsState() called before client initialized; using last known values from data store");
                }
                else
                {
                    _evalLog.Warn("AllFlagsState() called before client initialized; data store unavailable, returning empty state");
                    return(new FeatureFlagsState(false));
                }
            }
            if (user == null || user.Key == null)
            {
                _evalLog.Warn("AllFlagsState() called with null user or null user key; returning empty state");
                return(new FeatureFlagsState(false));
            }

            var builder              = new FeatureFlagsStateBuilder(options);
            var clientSideOnly       = FlagsStateOption.HasOption(options, FlagsStateOption.ClientSideOnly);
            var withReasons          = FlagsStateOption.HasOption(options, FlagsStateOption.WithReasons);
            var detailsOnlyIfTracked = FlagsStateOption.HasOption(options, FlagsStateOption.DetailsOnlyForTrackedFlags);
            KeyedItems <ItemDescriptor> flags;

            try
            {
                flags = _dataStore.GetAll(DataModel.Features);
            }
            catch (Exception e)
            {
                LogHelpers.LogException(_log, "Exception while retrieving flags for AllFlagsState", e);
                return(new FeatureFlagsState(false));
            }
            foreach (var pair in flags.Items)
            {
                if (pair.Value.Item is null || !(pair.Value.Item is FeatureFlag flag))
                {
                    continue;
                }
                if (clientSideOnly && !flag.ClientSide)
                {
                    continue;
                }
                try
                {
                    Evaluator.EvalResult result = _evaluator.Evaluate(flag, user, EventFactory.Default);
                    builder.AddFlag(flag.Key, result.Result.Value, result.Result.VariationIndex,
                                    result.Result.Reason, flag.Version, flag.TrackEvents, flag.DebugEventsUntilDate);
                }
                catch (Exception e)
                {
                    LogHelpers.LogException(_evalLog,
                                            string.Format("Exception caught for feature flag \"{0}\" when evaluating all flags", flag.Key),
                                            e);
                    EvaluationReason reason = EvaluationReason.ErrorReason(EvaluationErrorKind.Exception);
                    builder.AddFlag(flag.Key, new EvaluationDetail <LdValue>(LdValue.Null, null, reason));
                }
            }
            return(builder.Build());
        }