Skip to content

Commit

Permalink
refactor: isolate flag state management to store (#383)
Browse files Browse the repository at this point in the history
<!-- Please use this template for your pull request. -->
<!-- Please use the sections that you need and delete other sections -->

## This PR
<!-- add the description of the PR here -->

- Isolates flag state management to store package

### Related Issues
<!-- add here the GitHub issue that this PR resolves if applicable -->

Fixes #371 

### Notes
<!-- any additional notes for this PR -->

### Follow-up Tasks
<!-- anything that is related to this PR but not done here should be
noted under this section -->
<!-- if there is a need for a new issue, please link it here -->

### How to test
<!-- if applicable, add testing instructions under this section -->
I've ran [flagd's integration
tests](#312) against this
build to ensure behaviour is as before.

---------

Signed-off-by: Skye Gill <gill.skye95@gmail.com>
  • Loading branch information
skyerus authored Feb 9, 2023
1 parent beb7564 commit fef9b87
Show file tree
Hide file tree
Showing 13 changed files with 377 additions and 2,039 deletions.
Binary file modified docs/images/of-flagd-0.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1,629 changes: 0 additions & 1,629 deletions docs/images/of-flagd-1-source.excalidraw

This file was deleted.

Binary file modified docs/images/of-flagd-1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 2 additions & 3 deletions docs/other_resources/high_level_architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ for flag configuration change notifications.
The sync component has implementations to update flag configurations from various sources. The current implementation
contain sync providers for files, K8s resources and HTTP endpoints.

The evaluator engine stores flag configurations updated from sync providers and perform the feature flag evaluations
based on evaluation requests coming from feature flag libraries.
The evaluation engine's role is twofold, it acts as an intermediary between configuration changes and the state store by interpreting change events and forwarding the necessary changes to the state store. It also performs the feature flag evaluations based on evaluation requests coming from feature flag libraries.

The Runtime stays in between these components and coordinates operations.

Expand All @@ -24,7 +23,7 @@ The Sync component contains implementations of the ISync interface. The interfac
flag configurations watched by the respective implementation. For example, the file sync provider watches for a change
(ex: - add, modify, remove) of a specific file in the file system.

The update provided by sync implementation is pushed to the evaluator engine and change notifications generated in the
The update provided by sync implementation is pushed to the evaluator engine, which interprets the event and forwards it to the state store. Change notifications generated in the
process gets pushed to event subscribers.

<img src="../images/of-flagd-1.png" width="560">
26 changes: 0 additions & 26 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bufbuild/connect-go v1.4.1 h1:6usL3JGjKhxQpvDlizP7u8VfjAr1JkckcAUbrdcbgNY=
github.com/bufbuild/connect-go v1.4.1/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I=
github.com/bufbuild/connect-go v1.5.0 h1:IfbgbzzaaZvF+OM3SfxO2EjtvNJarNAz2DIRuuNjAgc=
github.com/bufbuild/connect-go v1.5.0/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I=
github.com/bufbuild/connect-go v1.5.1 h1:ORhrSiu63hWxtuMmC/V1mKySSRhEySsW5RkHJcyJXBk=
github.com/bufbuild/connect-go v1.5.1/go.mod h1:9iNvh/NOsfhNBUH5CtvXeVUskQO1xsrEviH7ZArwZ3I=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down Expand Up @@ -285,14 +281,6 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo/v2 v2.6.0 h1:9t9b9vRUbFq3C4qKFCGkVuq/fIHji802N1nrtkh1mNc=
github.com/onsi/gomega v1.24.1 h1:KORJXNNTzJXzu4ScJWssJfJMnJ+2QJqhoQSRwNlze9E=
github.com/open-feature/open-feature-operator v0.2.24 h1:6UwfHO7pa2WDDpdyL+hzYwukbooAA2IZFgyj5xga2vw=
github.com/open-feature/open-feature-operator v0.2.24/go.mod h1:6zsu3m2sa8b4qJlHIAp1Kuc80mCAOAkBCkvDTTyv9ZY=
github.com/open-feature/open-feature-operator v0.2.25 h1:6X1dn7YTTCxRj7Sq6NR3ThDvXYt+4VPPC1GP7D5GD+Q=
github.com/open-feature/open-feature-operator v0.2.25/go.mod h1:8OFtVXXdVpZTSx1vHravbTYup4iyeb+PLmiKbRL11TA=
github.com/open-feature/open-feature-operator v0.2.26 h1:nv3Bln6Zvkc0fXz1/XpQR5TtiXn8KZ/9r85y/jWGNE0=
github.com/open-feature/open-feature-operator v0.2.26/go.mod h1:bQncVK7hvhj5QStPwexxQ1aArPwox2Y1vWrVei/qIFg=
github.com/open-feature/open-feature-operator v0.2.27 h1:OIPEVrEOK39mLeImKrcLnd1AVClj7VrEMOtnZjHLXxY=
github.com/open-feature/open-feature-operator v0.2.27/go.mod h1:bQncVK7hvhj5QStPwexxQ1aArPwox2Y1vWrVei/qIFg=
github.com/open-feature/open-feature-operator v0.2.28 h1:qzzVq8v9G7aXO7luocO/wQCGnTJjtcQh75mDOqjnFxo=
github.com/open-feature/open-feature-operator v0.2.28/go.mod h1:bQncVK7hvhj5QStPwexxQ1aArPwox2Y1vWrVei/qIFg=
github.com/open-feature/schemas v0.2.8 h1:oA75hJXpOd9SFgmNI2IAxWZkwzQPUDm7Jyyh3q489wM=
Expand Down Expand Up @@ -737,10 +725,6 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
google.golang.org/grpc v1.52.0 h1:kd48UiU7EHsV4rnLyOJRuP/Il/UHE7gdDAQ+SZI7nZk=
google.golang.org/grpc v1.52.0/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.52.1 h1:2NpOPk5g5Xtb0qebIEs7hNIa++PdtZLo2AQUpc1YnSU=
google.golang.org/grpc v1.52.1/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.52.3 h1:pf7sOysg4LdgBqduXveGKrcEwbStiK2rtfghdzlUYDQ=
google.golang.org/grpc v1.52.3/go.mod h1:pu6fVzoFb+NBYNAvQL08ic+lvB2IojljRYuun5vorUY=
google.golang.org/grpc v1.53.0 h1:LAv2ds7cmFV/XTS3XG1NneeENYrXGmorPxsBbptIjNc=
Expand Down Expand Up @@ -793,16 +777,12 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
k8s.io/apiextensions-apiserver v0.26.0 h1:Gy93Xo1eg2ZIkNX/8vy5xviVSxwQulsnUdQ00nEdpDo=
k8s.io/apiextensions-apiserver v0.26.0/go.mod h1:7ez0LTiyW5nq3vADtK6C3kMESxadD51Bh6uz3JOlqWQ=
k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI=
k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM=
k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
k8s.io/component-base v0.26.0 h1:0IkChOCohtDHttmKuz+EP3j3+qKmV55rM9gIFTXA7Vs=
k8s.io/component-base v0.26.0/go.mod h1:lqHwlfV1/haa14F/Z5Zizk5QmzaVf23nQzCwVOQpfC8=
k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
Expand All @@ -814,12 +794,6 @@ k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
sigs.k8s.io/controller-runtime v0.14.1 h1:vThDes9pzg0Y+UbCPY3Wj34CGIYPgdmspPm2GIpxpzM=
sigs.k8s.io/controller-runtime v0.14.1/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU=
sigs.k8s.io/controller-runtime v0.14.2 h1:P6IwDhbsRWsBClt/8/h8Zy36bCuGuW5Op7MHpFrN/60=
sigs.k8s.io/controller-runtime v0.14.2/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
sigs.k8s.io/controller-runtime v0.14.3 h1:F1JutCoGfSDRiayjAaWcB8SC4BwIt6qkZ/TwiVY8ZRI=
sigs.k8s.io/controller-runtime v0.14.3/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
sigs.k8s.io/controller-runtime v0.14.4 h1:Kd/Qgx5pd2XUL08eOV2vwIq3L9GhIbJ5Nxengbd4/0M=
sigs.k8s.io/controller-runtime v0.14.4/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
Expand Down
28 changes: 12 additions & 16 deletions pkg/eval/fractional_evaluation_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package eval

import (
"sync"
"testing"

"github.com/open-feature/flagd/pkg/store"

"github.com/open-feature/flagd/pkg/logger"
"github.com/open-feature/flagd/pkg/model"
"google.golang.org/protobuf/types/known/structpb"
)

func TestFractionalEvaluation(t *testing.T) {
flags := Flags{
mx: &sync.RWMutex{},
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -115,8 +115,7 @@ func TestFractionalEvaluation(t *testing.T) {
},
"non even split": {
flags: Flags{
mx: &sync.RWMutex{},
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -167,8 +166,7 @@ func TestFractionalEvaluation(t *testing.T) {
},
"fallback to default variant if no email provided": {
flags: Flags{
mx: &sync.RWMutex{},
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -210,8 +208,7 @@ func TestFractionalEvaluation(t *testing.T) {
},
"fallback to default variant if invalid variant as result of fractional evaluation": {
flags: Flags{
mx: &sync.RWMutex{},
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -245,8 +242,7 @@ func TestFractionalEvaluation(t *testing.T) {
},
"fallback to default variant if percentages don't sum to 100": {
flags: Flags{
mx: &sync.RWMutex{},
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -287,10 +283,10 @@ func TestFractionalEvaluation(t *testing.T) {
for name, tt := range tests {
t.Run(name, func(t *testing.T) {
je := NewJSONEvaluator(logger.NewLogger(nil, false))
je.state = tt.flags
je.store.Flags = tt.flags.Flags

value, variant, reason, err := resolve[string](
reqID, tt.flagKey, tt.context, je.evaluateVariant, je.state.Flags[tt.flagKey].Variants,
reqID, tt.flagKey, tt.context, je.evaluateVariant, je.store.Flags[tt.flagKey].Variants,
)

if value != tt.expectedValue {
Expand All @@ -314,7 +310,7 @@ func TestFractionalEvaluation(t *testing.T) {

func BenchmarkFractionalEvaluation(b *testing.B) {
flags := Flags{
Flags: map[string]Flag{
Flags: map[string]model.Flag{
"headerColor": {
State: "ENABLED",
DefaultVariant: "red",
Expand Down Expand Up @@ -419,10 +415,10 @@ func BenchmarkFractionalEvaluation(b *testing.B) {
reqID := "test"
for name, tt := range tests {
b.Run(name, func(b *testing.B) {
je := JSONEvaluator{state: tt.flags}
je := JSONEvaluator{store: &store.Flags{Flags: tt.flags.Flags}}
for i := 0; i < b.N; i++ {
value, variant, reason, err := resolve[string](
reqID, tt.flagKey, tt.context, je.evaluateVariant, je.state.Flags[tt.flagKey].Variants,
reqID, tt.flagKey, tt.context, je.evaluateVariant, je.store.Flags[tt.flagKey].Variants,
)

if value != tt.expectedValue {
Expand Down
14 changes: 0 additions & 14 deletions pkg/eval/ievaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,6 @@ import (
"google.golang.org/protobuf/types/known/structpb"
)

type StateChangeNotificationType string

const (
NotificationDelete StateChangeNotificationType = "delete"
NotificationCreate StateChangeNotificationType = "write"
NotificationUpdate StateChangeNotificationType = "update"
)

type StateChangeNotification struct {
Type StateChangeNotificationType `json:"type"`
Source string `json:"source"`
FlagKey string `json:"flagKey"`
}

type AnyValue struct {
Value interface{}
Variant string
Expand Down
63 changes: 25 additions & 38 deletions pkg/eval/json_evaluator.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"regexp"
"strconv"
"strings"
mxSync "sync"

"github.com/open-feature/flagd/pkg/store"
"github.com/open-feature/flagd/pkg/sync"

"github.com/diegoholiveira/jsonlogic/v3"
Expand All @@ -28,7 +28,7 @@ func init() {
}

type JSONEvaluator struct {
state Flags
store *store.Flags
Logger *logger.Logger
}

Expand All @@ -46,21 +46,14 @@ func NewJSONEvaluator(logger *logger.Logger) *JSONEvaluator {
zap.String("component", "evaluator"),
zap.String("evaluator", "json"),
),
state: Flags{
Flags: map[string]Flag{},
mx: &mxSync.RWMutex{},
},
store: store.NewFlags(),
}
jsonlogic.AddOperator("fractionalEvaluation", ev.fractionalEvaluation)
return &ev
}

func (je *JSONEvaluator) GetState() (string, error) {
data, err := json.Marshal(&je.state)
if err != nil {
return "", err
}
return string(data), nil
return je.store.String()
}

func (je *JSONEvaluator) SetState(payload sync.DataSync) (map[string]interface{}, error) {
Expand All @@ -72,13 +65,13 @@ func (je *JSONEvaluator) SetState(payload sync.DataSync) (map[string]interface{}

switch payload.Type {
case sync.ALL:
return je.state.Merge(je.Logger, payload.Source, newFlags), nil
return je.store.Merge(je.Logger, payload.Source, newFlags.Flags), nil
case sync.ADD:
return je.state.Add(je.Logger, payload.Source, newFlags), nil
return je.store.Add(je.Logger, payload.Source, newFlags.Flags), nil
case sync.UPDATE:
return je.state.Update(je.Logger, payload.Source, newFlags), nil
return je.store.Update(je.Logger, payload.Source, newFlags.Flags), nil
case sync.DELETE:
return je.state.Delete(je.Logger, payload.Source, newFlags), nil
return je.store.DeleteFlags(je.Logger, payload.Source, newFlags.Flags), nil
default:
return nil, fmt.Errorf("unsupported sync type: %d", payload.Type)
}
Expand Down Expand Up @@ -112,9 +105,8 @@ func (je *JSONEvaluator) ResolveAllValues(reqID string, context *structpb.Struct
var variant string
var reason string
var err error
je.state.mx.RLock()
defer je.state.mx.RUnlock()
for flagKey, flag := range je.state.Flags {
allFlags := je.store.GetAll()
for flagKey, flag := range allFlags {
defaultValue := flag.Variants[flag.DefaultVariant]
switch defaultValue.(type) {
case bool:
Expand All @@ -123,31 +115,31 @@ func (je *JSONEvaluator) ResolveAllValues(reqID string, context *structpb.Struct
flagKey,
context,
je.evaluateVariant,
je.state.Flags[flagKey].Variants,
allFlags[flagKey].Variants,
)
case string:
value, variant, reason, err = resolve[string](
reqID,
flagKey,
context,
je.evaluateVariant,
je.state.Flags[flagKey].Variants,
allFlags[flagKey].Variants,
)
case float64:
value, variant, reason, err = resolve[float64](
reqID,
flagKey,
context,
je.evaluateVariant,
je.state.Flags[flagKey].Variants,
allFlags[flagKey].Variants,
)
case map[string]any:
value, variant, reason, err = resolve[map[string]any](
reqID,
flagKey,
context,
je.evaluateVariant,
je.state.Flags[flagKey].Variants,
allFlags[flagKey].Variants,
)
}
if err != nil {
Expand All @@ -165,10 +157,9 @@ func (je *JSONEvaluator) ResolveBooleanValue(reqID string, flagKey string, conte
reason string,
err error,
) {
je.state.mx.RLock()
defer je.state.mx.RUnlock()
je.Logger.DebugWithID(reqID, fmt.Sprintf("evaluating boolean flag: %s", flagKey))
return resolve[bool](reqID, flagKey, context, je.evaluateVariant, je.state.Flags[flagKey].Variants)
flag, _ := je.store.Get(flagKey)
return resolve[bool](reqID, flagKey, context, je.evaluateVariant, flag.Variants)
}

func (je *JSONEvaluator) ResolveStringValue(reqID string, flagKey string, context *structpb.Struct) (
Expand All @@ -177,10 +168,9 @@ func (je *JSONEvaluator) ResolveStringValue(reqID string, flagKey string, contex
reason string,
err error,
) {
je.state.mx.RLock()
defer je.state.mx.RUnlock()
je.Logger.DebugWithID(reqID, fmt.Sprintf("evaluating string flag: %s", flagKey))
return resolve[string](reqID, flagKey, context, je.evaluateVariant, je.state.Flags[flagKey].Variants)
flag, _ := je.store.Get(flagKey)
return resolve[string](reqID, flagKey, context, je.evaluateVariant, flag.Variants)
}

func (je *JSONEvaluator) ResolveFloatValue(reqID string, flagKey string, context *structpb.Struct) (
Expand All @@ -189,11 +179,10 @@ func (je *JSONEvaluator) ResolveFloatValue(reqID string, flagKey string, context
reason string,
err error,
) {
je.state.mx.RLock()
defer je.state.mx.RUnlock()
je.Logger.DebugWithID(reqID, fmt.Sprintf("evaluating float flag: %s", flagKey))
flag, _ := je.store.Get(flagKey)
value, variant, reason, err = resolve[float64](
reqID, flagKey, context, je.evaluateVariant, je.state.Flags[flagKey].Variants)
reqID, flagKey, context, je.evaluateVariant, flag.Variants)
return
}

Expand All @@ -203,12 +192,11 @@ func (je *JSONEvaluator) ResolveIntValue(reqID string, flagKey string, context *
reason string,
err error,
) {
je.state.mx.RLock()
defer je.state.mx.RUnlock()
je.Logger.DebugWithID(reqID, fmt.Sprintf("evaluating int flag: %s", flagKey))
flag, _ := je.store.Get(flagKey)
var val float64
val, variant, reason, err = resolve[float64](
reqID, flagKey, context, je.evaluateVariant, je.state.Flags[flagKey].Variants)
reqID, flagKey, context, je.evaluateVariant, flag.Variants)
value = int64(val)
return
}
Expand All @@ -219,10 +207,9 @@ func (je *JSONEvaluator) ResolveObjectValue(reqID string, flagKey string, contex
reason string,
err error,
) {
je.state.mx.RLock()
defer je.state.mx.RUnlock()
je.Logger.DebugWithID(reqID, fmt.Sprintf("evaluating object flag: %s", flagKey))
return resolve[map[string]any](reqID, flagKey, context, je.evaluateVariant, je.state.Flags[flagKey].Variants)
flag, _ := je.store.Get(flagKey)
return resolve[map[string]any](reqID, flagKey, context, je.evaluateVariant, flag.Variants)
}

// runs the rules (if defined) to determine the variant, otherwise falling through to the default
Expand All @@ -231,7 +218,7 @@ func (je *JSONEvaluator) evaluateVariant(
flagKey string,
context *structpb.Struct,
) (variant string, reason string, err error) {
flag, ok := je.state.Flags[flagKey]
flag, ok := je.store.Get(flagKey)
if !ok {
// flag not found
je.Logger.DebugWithID(reqID, fmt.Sprintf("requested flag could not be found: %s", flagKey))
Expand Down
Loading

0 comments on commit fef9b87

Please sign in to comment.