Skip to content

Commit 5c5c1cf

Browse files
authored
chore(refactor): use memdb for flag storage (#1697)
This PR contains no behavioral changes, and no breaking changes. It lays the groundwork for some of the upcoming improvements we want in flagd, as specified in recent ADRs. It does this by re-implementing our storage layer to use [go-memdb](https://github.com/hashicorp/go-memdb), an open source in-memory database developed by Hashicorp and used in [Consul](https://developer.hashicorp.com/consul) (as well as MANY other projects). ### Why? This will allow us to easily support: - duplicate flag keys (namespaced by flagSetId), as mentioned in [this ADR](https://github.com/open-feature/flagd/blob/main/docs/architecture-decisions/duplicate-flag-keys.md) - robust flag selectors, as mentioned in [this ADR](#1644), by supporting "watchers" which allow us to "listen" to change in flags returned by a given query 🕺 - robust (and possibly, in the future, even customizable) indexing on arbitrary attributes (to easily support fetching "all boolean flags", or "flags with metadata = xyz", etc) - cross-"table" transactions I have already PoC'd that these are all practical. ### Changes in implementation - the `store` package's `State` is no longer just a struct; it's a object with methods wrapping the internal db - the `store` package's `State` was renamed to `Store` and the file was renamed from `flags.go` to `store.go`, since it's ceased to be a simple stateful object, and for consistency - a non-serialized (used only internally) `Key` field was added to the flag type (for indexing) - a new constructor for the `Store` was added which takes a logger and returns an error, the old was deprecated to avoid breaking changes in consumers (the Go flagd provider, mostly) Note that the go-memdb dependency is MPL2, which is not allowed by the CNCF, however, go-memdb is already used in CNCF projects and has a [special exception](https://github.com/cncf/foundation/blob/347a55dc0a6c6dc3d55a9a782e5701080a8ec43b/license-exceptions/cncf-exceptions-2023-08-31.json#L7-L11). ### Perfromance There was no significant change in performance, see benchmark diff vs main below: <details> <summary>Benchmark diff vs main</summary> ```diff -BenchmarkFractionalEvaluation/[email protected] 559051 13832 ns/op 7229 B/op 135 allocs/op -BenchmarkFractionalEvaluation/[email protected] 611665 13106 ns/op 7229 B/op 135 allocs/op -BenchmarkFractionalEvaluation/[email protected] 383074 13433 ns/op 7229 B/op 135 allocs/op -BenchmarkFractionalEvaluation/[email protected] 529185 12190 ns/op 7229 B/op 135 allocs/op -BenchmarkResolveBooleanValue/test_staticBoolFlag-16 3929409 1712 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveBooleanValue/test_targetingBoolFlag-16 812671 10276 ns/op 6065 B/op 87 allocs/op -BenchmarkResolveBooleanValue/test_staticObjectFlag-16 4398327 1700 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveBooleanValue/test_missingFlag-16 4541409 1494 ns/op 784 B/op 12 allocs/op -BenchmarkResolveBooleanValue/test_disabledFlag-16 2998599 1815 ns/op 1072 B/op 13 allocs/op -BenchmarkResolveStringValue/test_staticStringFlag-16 4378830 1698 ns/op 1040 B/op 13 allocs/op -BenchmarkResolveStringValue/test_targetingStringFlag-16 849668 9165 ns/op 6097 B/op 89 allocs/op -BenchmarkResolveStringValue/test_staticObjectFlag-16 4560192 1363 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveStringValue/test_missingFlag-16 5283511 1196 ns/op 784 B/op 12 allocs/op -BenchmarkResolveStringValue/test_disabledFlag-16 4393116 1446 ns/op 1072 B/op 13 allocs/op -BenchmarkResolveFloatValue/test:_staticFloatFlag-16 4264772 1501 ns/op 1024 B/op 13 allocs/op -BenchmarkResolveFloatValue/test:_targetingFloatFlag-16 776436 8191 ns/op 6081 B/op 89 allocs/op -BenchmarkResolveFloatValue/test:_staticObjectFlag-16 4685841 1285 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveFloatValue/test:_missingFlag-16 5001636 1376 ns/op 784 B/op 12 allocs/op -BenchmarkResolveFloatValue/test:_disabledFlag-16 3707120 1897 ns/op 1072 B/op 13 allocs/op -BenchmarkResolveIntValue/test_staticIntFlag-16 3770362 1677 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveIntValue/test_targetingNumberFlag-16 739861 11142 ns/op 6065 B/op 87 allocs/op -BenchmarkResolveIntValue/test_staticObjectFlag-16 4221418 1913 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveIntValue/test_missingFlag-16 4289516 1488 ns/op 768 B/op 12 allocs/op -BenchmarkResolveIntValue/test_disabledFlag-16 4027533 1829 ns/op 1072 B/op 13 allocs/op -BenchmarkResolveObjectValue/test_staticObjectFlag-16 1588855 3880 ns/op 2243 B/op 37 allocs/op -BenchmarkResolveObjectValue/test_targetingObjectFlag-16 562364 11580 ns/op 7283 B/op 109 allocs/op -BenchmarkResolveObjectValue/test_staticBoolFlag-16 5026976 1791 ns/op 1008 B/op 11 allocs/op -BenchmarkResolveObjectValue/test_missingFlag-16 4254043 1553 ns/op 784 B/op 12 allocs/op -BenchmarkResolveObjectValue/test_disabledFlag-16 3051976 2250 ns/op 1072 B/op 13 allocs/op +BenchmarkFractionalEvaluation/[email protected] 478593 14527 ns/op 7467 B/op 143 allocs/op +BenchmarkFractionalEvaluation/[email protected] 429560 14728 ns/op 7467 B/op 143 allocs/op +BenchmarkFractionalEvaluation/[email protected] 574078 14230 ns/op 7467 B/op 143 allocs/op +BenchmarkFractionalEvaluation/[email protected] 411690 15296 ns/op 7467 B/op 143 allocs/op +BenchmarkResolveBooleanValue/test_staticBoolFlag-16 4133443 1973 ns/op 960 B/op 18 allocs/op +BenchmarkResolveBooleanValue/test_targetingBoolFlag-16 822934 10981 ns/op 6033 B/op 94 allocs/op +BenchmarkResolveBooleanValue/test_staticObjectFlag-16 3955728 1964 ns/op 976 B/op 18 allocs/op +BenchmarkResolveBooleanValue/test_missingFlag-16 3068791 2294 ns/op 1064 B/op 21 allocs/op +BenchmarkResolveBooleanValue/test_disabledFlag-16 3500334 2225 ns/op 1024 B/op 20 allocs/op +BenchmarkResolveStringValue/test_staticStringFlag-16 3935048 1781 ns/op 1008 B/op 20 allocs/op +BenchmarkResolveStringValue/test_targetingStringFlag-16 770565 10765 ns/op 6065 B/op 96 allocs/op +BenchmarkResolveStringValue/test_staticObjectFlag-16 3896060 2084 ns/op 976 B/op 18 allocs/op +BenchmarkResolveStringValue/test_missingFlag-16 3103950 2141 ns/op 1064 B/op 21 allocs/op +BenchmarkResolveStringValue/test_disabledFlag-16 3717013 2092 ns/op 1024 B/op 20 allocs/op +BenchmarkResolveFloatValue/test:_staticFloatFlag-16 3971438 2003 ns/op 976 B/op 20 allocs/op +BenchmarkResolveFloatValue/test:_targetingFloatFlag-16 782996 10153 ns/op 6049 B/op 96 allocs/op +BenchmarkResolveFloatValue/test:_staticObjectFlag-16 3469644 2115 ns/op 976 B/op 18 allocs/op +BenchmarkResolveFloatValue/test:_missingFlag-16 3376167 2157 ns/op 1064 B/op 21 allocs/op +BenchmarkResolveFloatValue/test:_disabledFlag-16 3610095 2032 ns/op 1024 B/op 20 allocs/op +BenchmarkResolveIntValue/test_staticIntFlag-16 3883299 1941 ns/op 960 B/op 18 allocs/op +BenchmarkResolveIntValue/test_targetingNumberFlag-16 823038 10725 ns/op 6033 B/op 94 allocs/op +BenchmarkResolveIntValue/test_staticObjectFlag-16 3697454 2028 ns/op 976 B/op 18 allocs/op +BenchmarkResolveIntValue/test_missingFlag-16 3326895 1986 ns/op 1048 B/op 21 allocs/op +BenchmarkResolveIntValue/test_disabledFlag-16 3327046 2142 ns/op 1024 B/op 20 allocs/op +BenchmarkResolveObjectValue/test_staticObjectFlag-16 1534627 4885 ns/op 2211 B/op 44 allocs/op +BenchmarkResolveObjectValue/test_targetingObjectFlag-16 509614 14640 ns/op 7251 B/op 116 allocs/op +BenchmarkResolveObjectValue/test_staticBoolFlag-16 3871867 1978 ns/op 960 B/op 18 allocs/op +BenchmarkResolveObjectValue/test_missingFlag-16 3484065 2080 ns/op 1064 B/op 21 allocs/op +BenchmarkResolveObjectValue/test_disabledFlag-16 4013230 2158 ns/op 1024 B/op 20 allocs/op PASS -ok github.com/open-feature/flagd/core/pkg/evaluator 233.286s +ok github.com/open-feature/flagd/core/pkg/evaluator 261.212s ? github.com/open-feature/flagd/core/pkg/evaluator/mock [no test files] PASS -ok github.com/open-feature/flagd/core/pkg/logger 0.003s +ok github.com/open-feature/flagd/core/pkg/logger 0.002s ? github.com/open-feature/flagd/core/pkg/model [no test files] ? github.com/open-feature/flagd/core/pkg/service [no test files] PASS -ok github.com/open-feature/flagd/core/pkg/service/ofrep 0.003s +ok github.com/open-feature/flagd/core/pkg/service/ofrep 0.002s PASS ok github.com/open-feature/flagd/core/pkg/store 0.002s ? github.com/open-feature/flagd/core/pkg/sync [no test files] @@ -51,9 +51,9 @@ PASS ok github.com/open-feature/flagd/core/pkg/sync/builder 0.020s ? github.com/open-feature/flagd/core/pkg/sync/builder/mock [no test files] PASS -ok github.com/open-feature/flagd/core/pkg/sync/file 1.007s +ok github.com/open-feature/flagd/core/pkg/sync/file 1.006s PASS -ok github.com/open-feature/flagd/core/pkg/sync/grpc 8.014s +ok github.com/open-feature/flagd/core/pkg/sync/grpc 8.013s PASS ok github.com/open-feature/flagd/core/pkg/sync/grpc/credentials 0.004s ? github.com/open-feature/flagd/core/pkg/sync/grpc/credentials/mock [no test files] @@ -61,10 +61,10 @@ ok github.com/open-feature/flagd/core/pkg/sync/grpc/credentials 0.004s PASS ok github.com/open-feature/flagd/core/pkg/sync/grpc/nameresolvers 0.002s PASS -ok github.com/open-feature/flagd/core/pkg/sync/http 4.008s +ok github.com/open-feature/flagd/core/pkg/sync/http 4.007s ? github.com/open-feature/flagd/core/pkg/sync/http/mock [no test files] PASS -ok github.com/open-feature/flagd/core/pkg/sync/kubernetes 0.015s +ok github.com/open-feature/flagd/core/pkg/sync/kubernetes 0.016s ? github.com/open-feature/flagd/core/pkg/sync/testing [no test files] PASS ok github.com/open-feature/flagd/core/pkg/telemetry 0.016s ``` </details> --------- Signed-off-by: Todd Baert <[email protected]>
1 parent 2f49ea7 commit 5c5c1cf

File tree

21 files changed

+465
-462
lines changed

21 files changed

+465
-462
lines changed

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ flagd-integration-test: # dependent on ./bin/flagd start -f file:test-harness/fl
5151
go test -cover ./test/integration $(ARGS)
5252
flagd-benchmark-test:
5353
go test -bench=Bench -short -benchtime=5s -benchmem ./core/... | tee benchmark.txt
54+
flagd-integration-test-harness:
55+
# target used to start a locally built flagd with the e2e flags
56+
cd flagd; go run main.go start -f file:../test-harness/flags/testing-flags.json -f file:../test-harness/flags/custom-ops.json -f file:../test-harness/flags/evaluator-refs.json -f file:../test-harness/flags/zero-flags.json -f file:../test-harness/flags/edge-case-flags.json
57+
flagd-integration-test: # dependent on flagd-e2e-test-harness if not running in github actions
58+
go test -count=1 -cover ./test/integration $(ARGS)
5459
run: # default to flagd
5560
make run-flagd
5661
run-flagd:

benchmark.txt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
PASS
2+
ok github.com/open-feature/flagd/core/pkg/certreloader 15.986s
3+
goos: linux
4+
goarch: amd64
5+
pkg: github.com/open-feature/flagd/core/pkg/evaluator
6+
cpu: 11th Gen Intel(R) Core(TM) i9-11950H @ 2.60GHz
7+
BenchmarkFractionalEvaluation/[email protected] 423930 13316 ns/op 7229 B/op 135 allocs/op
8+
BenchmarkFractionalEvaluation/[email protected] 469594 13677 ns/op 7229 B/op 135 allocs/op
9+
BenchmarkFractionalEvaluation/[email protected] 569103 13286 ns/op 7229 B/op 135 allocs/op
10+
BenchmarkFractionalEvaluation/[email protected] 412386 13023 ns/op 7229 B/op 135 allocs/op
11+
BenchmarkResolveBooleanValue/test_staticBoolFlag-16 3106903 1792 ns/op 1008 B/op 11 allocs/op
12+
BenchmarkResolveBooleanValue/test_targetingBoolFlag-16 448164 11250 ns/op 6065 B/op 87 allocs/op
13+
BenchmarkResolveBooleanValue/test_staticObjectFlag-16 3958750 1476 ns/op 1008 B/op 11 allocs/op
14+
BenchmarkResolveBooleanValue/test_missingFlag-16 5331808 1353 ns/op 784 B/op 12 allocs/op
15+
BenchmarkResolveBooleanValue/test_disabledFlag-16 4530751 1301 ns/op 1072 B/op 13 allocs/op
16+
BenchmarkResolveStringValue/test_staticStringFlag-16 4583056 1525 ns/op 1040 B/op 13 allocs/op
17+
BenchmarkResolveStringValue/test_targetingStringFlag-16 839954 10388 ns/op 6097 B/op 89 allocs/op
18+
BenchmarkResolveStringValue/test_staticObjectFlag-16 4252830 1677 ns/op 1008 B/op 11 allocs/op
19+
BenchmarkResolveStringValue/test_missingFlag-16 3743324 1495 ns/op 784 B/op 12 allocs/op
20+
BenchmarkResolveStringValue/test_disabledFlag-16 3495699 1709 ns/op 1072 B/op 13 allocs/op
21+
BenchmarkResolveFloatValue/test:_staticFloatFlag-16 4382868 1511 ns/op 1024 B/op 13 allocs/op
22+
BenchmarkResolveFloatValue/test:_targetingFloatFlag-16 867987 10344 ns/op 6081 B/op 89 allocs/op
23+
BenchmarkResolveFloatValue/test:_staticObjectFlag-16 3913120 1695 ns/op 1008 B/op 11 allocs/op
24+
BenchmarkResolveFloatValue/test:_missingFlag-16 3910468 1349 ns/op 784 B/op 12 allocs/op
25+
BenchmarkResolveFloatValue/test:_disabledFlag-16 3642919 1666 ns/op 1072 B/op 13 allocs/op
26+
BenchmarkResolveIntValue/test_staticIntFlag-16 4077288 1349 ns/op 1008 B/op 11 allocs/op
27+
BenchmarkResolveIntValue/test_targetingNumberFlag-16 922383 7601 ns/op 6065 B/op 87 allocs/op
28+
BenchmarkResolveIntValue/test_staticObjectFlag-16 4995128 1229 ns/op 1008 B/op 11 allocs/op
29+
BenchmarkResolveIntValue/test_missingFlag-16 5574153 1274 ns/op 768 B/op 12 allocs/op
30+
BenchmarkResolveIntValue/test_disabledFlag-16 3633708 1734 ns/op 1072 B/op 13 allocs/op
31+
BenchmarkResolveObjectValue/test_staticObjectFlag-16 1624102 4559 ns/op 2243 B/op 37 allocs/op
32+
BenchmarkResolveObjectValue/test_targetingObjectFlag-16 443880 11995 ns/op 7283 B/op 109 allocs/op
33+
BenchmarkResolveObjectValue/test_staticBoolFlag-16 3462445 1665 ns/op 1008 B/op 11 allocs/op
34+
BenchmarkResolveObjectValue/test_missingFlag-16 4207567 1458 ns/op 784 B/op 12 allocs/op
35+
BenchmarkResolveObjectValue/test_disabledFlag-16 3407262 1848 ns/op 1072 B/op 13 allocs/op
36+
PASS
37+
ok github.com/open-feature/flagd/core/pkg/evaluator 239.506s
38+
? github.com/open-feature/flagd/core/pkg/evaluator/mock [no test files]
39+
PASS
40+
ok github.com/open-feature/flagd/core/pkg/logger 0.003s
41+
? github.com/open-feature/flagd/core/pkg/model [no test files]
42+
? github.com/open-feature/flagd/core/pkg/service [no test files]
43+
PASS
44+
ok github.com/open-feature/flagd/core/pkg/service/ofrep 0.002s
45+
PASS
46+
ok github.com/open-feature/flagd/core/pkg/store 0.003s
47+
? github.com/open-feature/flagd/core/pkg/sync [no test files]
48+
PASS
49+
ok github.com/open-feature/flagd/core/pkg/sync/blob 0.016s
50+
PASS
51+
ok github.com/open-feature/flagd/core/pkg/sync/builder 0.018s
52+
? github.com/open-feature/flagd/core/pkg/sync/builder/mock [no test files]
53+
PASS
54+
ok github.com/open-feature/flagd/core/pkg/sync/file 1.007s
55+
PASS
56+
ok github.com/open-feature/flagd/core/pkg/sync/grpc 8.011s
57+
PASS
58+
ok github.com/open-feature/flagd/core/pkg/sync/grpc/credentials 0.008s
59+
? github.com/open-feature/flagd/core/pkg/sync/grpc/credentials/mock [no test files]
60+
? github.com/open-feature/flagd/core/pkg/sync/grpc/mock [no test files]
61+
PASS
62+
ok github.com/open-feature/flagd/core/pkg/sync/grpc/nameresolvers 0.002s
63+
PASS
64+
ok github.com/open-feature/flagd/core/pkg/sync/http 4.006s
65+
? github.com/open-feature/flagd/core/pkg/sync/http/mock [no test files]
66+
PASS
67+
ok github.com/open-feature/flagd/core/pkg/sync/kubernetes 0.016s
68+
? github.com/open-feature/flagd/core/pkg/sync/testing [no test files]
69+
PASS
70+
ok github.com/open-feature/flagd/core/pkg/telemetry 0.016s
71+
PASS
72+
ok github.com/open-feature/flagd/core/pkg/utils 0.002s

core/pkg/evaluator/fractional_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ func TestFractionalEvaluation(t *testing.T) {
459459
t.Run(name, func(t *testing.T) {
460460
log := logger.NewLogger(nil, false)
461461
je := NewJSON(log, store.NewFlags())
462-
je.store.Flags = tt.flags.Flags
462+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
463463

464464
value, variant, reason, _, err := resolve[string](ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)
465465

@@ -587,7 +587,8 @@ func BenchmarkFractionalEvaluation(b *testing.B) {
587587
for name, tt := range tests {
588588
b.Run(name, func(b *testing.B) {
589589
log := logger.NewLogger(nil, false)
590-
je := NewJSON(log, &store.State{Flags: tt.flags.Flags})
590+
je := NewJSON(log, store.NewFlags())
591+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
591592
for i := 0; i < b.N; i++ {
592593
value, variant, reason, _, err := resolve[string](
593594
ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)

core/pkg/evaluator/json.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,13 @@ func WithEvaluator(name string, evalFunc func(interface{}, interface{}) interfac
6464

6565
// JSON evaluator
6666
type JSON struct {
67-
store *store.State
67+
store *store.Store
6868
Logger *logger.Logger
6969
jsonEvalTracer trace.Tracer
7070
Resolver
7171
}
7272

73-
func NewJSON(logger *logger.Logger, s *store.State, opts ...JSONEvaluatorOption) *JSON {
73+
func NewJSON(logger *logger.Logger, s *store.Store, opts ...JSONEvaluatorOption) *JSON {
7474
logger = logger.WithFields(
7575
zap.String("component", "evaluator"),
7676
zap.String("evaluator", "json"),
@@ -118,7 +118,7 @@ func (je *JSON) SetState(payload sync.DataSync) (map[string]interface{}, bool, e
118118
var events map[string]interface{}
119119
var reSync bool
120120

121-
events, reSync = je.store.Update(je.Logger, payload.Source, payload.Selector, definition.Flags, definition.Metadata)
121+
events, reSync = je.store.Update(payload.Source, payload.Selector, definition.Flags, definition.Metadata)
122122

123123
// Number of events correlates to the number of flags changed through this sync, record it
124124
span.SetAttributes(attribute.Int("feature_flag.change_count", len(events)))

core/pkg/evaluator/json_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,8 +1377,8 @@ func TestState_Evaluator(t *testing.T) {
13771377
t.Fatal(err)
13781378
}
13791379

1380-
if !reflect.DeepEqual(expectedOutputJSON["flags"], gotOutputJSON["flags"]) {
1381-
t.Errorf("expected state: %v got state: %v", expectedOutputJSON, gotOutputJSON)
1380+
if !reflect.DeepEqual(expectedOutputJSON["flags"], gotOutputJSON) {
1381+
t.Errorf("expected state: %v got state: %v", expectedOutputJSON["flags"], gotOutputJSON)
13821382
}
13831383
})
13841384
}

core/pkg/evaluator/legacy_fractional_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ func TestLegacyFractionalEvaluation(t *testing.T) {
273273
t.Run(name, func(t *testing.T) {
274274
log := logger.NewLogger(nil, false)
275275
je := NewJSON(log, store.NewFlags())
276-
je.store.Flags = tt.flags.Flags
276+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
277277

278278
value, variant, reason, _, err := resolve[string](ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)
279279

core/pkg/evaluator/semver_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -923,7 +923,7 @@ func TestJSONEvaluator_semVerEvaluation(t *testing.T) {
923923
t.Run(name, func(t *testing.T) {
924924
log := logger.NewLogger(nil, false)
925925
je := NewJSON(log, store.NewFlags())
926-
je.store.Flags = tt.flags.Flags
926+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
927927

928928
value, variant, reason, _, err := resolve[string](ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)
929929

core/pkg/evaluator/string_comparison_test.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ func TestJSONEvaluator_startsWithEvaluation(t *testing.T) {
186186
t.Run(name, func(t *testing.T) {
187187
log := logger.NewLogger(nil, false)
188188
je := NewJSON(log, store.NewFlags())
189-
je.store.Flags = tt.flags.Flags
189+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
190190

191191
value, variant, reason, _, err := resolve[string](ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)
192192

@@ -383,8 +383,7 @@ func TestJSONEvaluator_endsWithEvaluation(t *testing.T) {
383383
t.Run(name, func(t *testing.T) {
384384
log := logger.NewLogger(nil, false)
385385
je := NewJSON(log, store.NewFlags())
386-
387-
je.store.Flags = tt.flags.Flags
386+
je.store.Update("", "", tt.flags.Flags, model.Metadata{})
388387

389388
value, variant, reason, _, err := resolve[string](ctx, reqID, tt.flagKey, tt.context, je.evaluateVariant)
390389

core/pkg/model/flag.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package model
33
import "encoding/json"
44

55
type Flag struct {
6+
Key string `json:"-"`
67
State string `json:"state"`
78
DefaultVariant string `json:"defaultVariant"`
89
Variants map[string]any `json:"variants"`

0 commit comments

Comments
 (0)