From 06e2c2a27706b7ace4978c6547990c7da759a526 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Wed, 21 Sep 2022 10:50:33 +0100 Subject: [PATCH 1/8] Update Go version in SDK --- .drone.yml | 4 ++-- .github/workflows/ci.yml | 2 +- docker/Dockerfile | 2 +- go.mod | 21 +++++++++++++++++++-- test_wrapper/go.mod | 2 +- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/.drone.yml b/.drone.yml index 9557315a..6c2de9e5 100644 --- a/.drone.yml +++ b/.drone.yml @@ -5,14 +5,14 @@ name: default steps: - name: check - image: golang:1.16.2 + image: golang:1.18.6 commands: - make check volumes: - name: gopath path: /go - name: test - image: golang:1.16.2 + image: golang:1.18.6 commands: - make test volumes: diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b2136026..141d2ba2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v2 with: - go-version: 1.16.2 + go-version: 1.18.6 - name: Check run: make check diff --git a/docker/Dockerfile b/docker/Dockerfile index 7801a37f..69e9fc77 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.16-alpine as builder +FROM golang:1.18.6-alpine as builder RUN apk update && apk add --no-cache make gcc musl-dev git ca-certificates && update-ca-certificates WORKDIR /app diff --git a/go.mod b/go.mod index 5ae2ac99..6835a392 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/harness/ff-golang-server-sdk -go 1.16 +go 1.18 require ( github.com/deepmap/oapi-codegen v1.11.0 @@ -16,7 +16,24 @@ require ( github.com/r3labs/sse v0.0.0-20201126193848-34e640891548 github.com/spaolacci/murmur3 v1.1.0 github.com/stretchr/testify v1.7.1 - go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.16.0 gopkg.in/cenkalti/backoff.v1 v1.1.0 ) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-openapi/jsonpointer v0.19.5 // indirect + github.com/go-openapi/swag v0.21.1 // indirect + github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + golang.org/x/net v0.0.0-20220513224357-95641704303c // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect +) diff --git a/test_wrapper/go.mod b/test_wrapper/go.mod index ebc75b02..35b00f32 100644 --- a/test_wrapper/go.mod +++ b/test_wrapper/go.mod @@ -1,6 +1,6 @@ module github.com/harness/ff-golang-server-sdk/test_wrapper -go 1.16 +go 1.18 replace github.com/harness/ff-golang-server-sdk => ../ From dfce6d296082fb93e838bf887cd9ec6006328dcc Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Wed, 21 Sep 2022 11:04:00 +0100 Subject: [PATCH 2/8] Add logic to allow user defined cache to be populated --- client/client.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/client/client.go b/client/client.go index 89e32917..6d20659d 100644 --- a/client/client.go +++ b/client/client.go @@ -86,11 +86,18 @@ func NewCfClient(sdkKey string, options ...ConfigOption) (*CfClient, error) { if sdkKey == "" { return client, types.ErrSdkCantBeEmpty } - lruCache, err := repository.NewLruCache(10000) - if err != nil { - return nil, err + + var err error + if client.config != nil { + client.repository = repository.New(config.Cache) + } else { + lruCache, err := repository.NewLruCache(10000) + if err != nil { + return nil, err + } + client.repository = repository.New(lruCache) } - client.repository = repository.New(lruCache) + client.evaluator, err = evaluation.NewEvaluator(client.repository, client, config.Logger) if err != nil { return nil, err From fe7b9508b33d852bd698180588cbe0fc3afc8cf6 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Tue, 27 Sep 2022 14:27:47 +0100 Subject: [PATCH 3/8] Add flag for initial load so that oldflag check doesn't occur on first load --- client/client.go | 4 ++-- pkg/repository/repository.go | 24 ++++++++++++++---------- stream/sse.go | 4 ++-- 3 files changed, 18 insertions(+), 14 deletions(-) diff --git a/client/client.go b/client/client.go index 6d20659d..daedcfa4 100644 --- a/client/client.go +++ b/client/client.go @@ -366,7 +366,7 @@ func (c *CfClient) retrieveFlags(ctx context.Context) error { } for _, flag := range *flags.JSON200 { - c.repository.SetFlag(flag) + c.repository.SetFlag(flag, true) } c.config.Logger.Info("Retrieving flags finished") return nil @@ -390,7 +390,7 @@ func (c *CfClient) retrieveSegments(ctx context.Context) error { } for _, segment := range *segments.JSON200 { - c.repository.SetSegment(segment) + c.repository.SetSegment(segment, true) } c.config.Logger.Info("Retrieving segments finished") return nil diff --git a/pkg/repository/repository.go b/pkg/repository/repository.go index a1dfed66..1ea3b049 100644 --- a/pkg/repository/repository.go +++ b/pkg/repository/repository.go @@ -13,8 +13,8 @@ type Repository interface { GetFlag(identifier string) (rest.FeatureConfig, error) GetSegment(identifier string) (rest.Segment, error) - SetFlag(featureConfig rest.FeatureConfig) - SetSegment(segment rest.Segment) + SetFlag(featureConfig rest.FeatureConfig, initialLoad bool) + SetSegment(segment rest.Segment, initialLoad bool) DeleteFlag(identifier string) DeleteSegment(identifier string) @@ -107,9 +107,11 @@ func (r FFRepository) GetSegment(identifier string) (rest.Segment, error) { } // SetFlag places a flag in the repository with the new value -func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig) { - if r.isFlagOutdated(featureConfig) { - return +func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig, initialLoad bool) { + if !initialLoad { + if r.isFlagOutdated(featureConfig) { + return + } } flagKey := formatFlagKey(featureConfig.Feature) if r.storage != nil { @@ -127,9 +129,11 @@ func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig) { } // SetSegment places a segment in the repository with the new value -func (r FFRepository) SetSegment(segment rest.Segment) { - if r.isSegmentOutdated(segment) { - return +func (r FFRepository) SetSegment(segment rest.Segment, initialLoad bool) { + if !initialLoad { + if r.isSegmentOutdated(segment) { + return + } } segmentKey := formatSegmentKey(segment.Identifier) if r.storage != nil { @@ -202,9 +206,9 @@ func (r FFRepository) Close() { } func formatFlagKey(identifier string) string { - return "flags/" + identifier + return "flag/" + identifier } func formatSegmentKey(identifier string) string { - return "segments/" + identifier + return "target-segment/" + identifier } diff --git a/stream/sse.go b/stream/sse.go index abf3d40d..8a514466 100644 --- a/stream/sse.go +++ b/stream/sse.go @@ -134,7 +134,7 @@ func (c *SSEClient) handleEvent(event Event) { } if response.JSON200 != nil { - c.repository.SetFlag(*response.JSON200) + c.repository.SetFlag(*response.JSON200, false) } } @@ -159,7 +159,7 @@ func (c *SSEClient) handleEvent(event Event) { return } if response.JSON200 != nil { - c.repository.SetSegment(*response.JSON200) + c.repository.SetSegment(*response.JSON200, false) } } updateWithTimeout() From 2a35117a407f2ba56c6d194aea0d70fe66a5e8a2 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Tue, 4 Oct 2022 14:50:16 +0100 Subject: [PATCH 4/8] Fix tests --- client/helpers_test.go | 8 +++++++- tests/evaluator_test.go | 4 ++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/client/helpers_test.go b/client/helpers_test.go index 12ef933a..4ce943ad 100644 --- a/client/helpers_test.go +++ b/client/helpers_test.go @@ -53,7 +53,13 @@ func MakeStringFeatureConfigs(name, defaultVariation, offVariation, state string // If there are any PreReqs then we need to store them as flags as well. for _, x := range preReqs { - featureConfig = append(featureConfig, MakeBoolFeatureConfig(x.Feature, "true", "false", x.Variations[0], nil)) + var state string + if x.Variations[0] == "true" { + state = "on" + } else { + state = "off" + } + featureConfig = append(featureConfig, MakeBoolFeatureConfig(x.Feature, "true", "false", state, nil)) } return featureConfig diff --git a/tests/evaluator_test.go b/tests/evaluator_test.go index 29b412bd..56b7ce85 100644 --- a/tests/evaluator_test.go +++ b/tests/evaluator_test.go @@ -84,10 +84,10 @@ func TestEvaluator(t *testing.T) { t.Error(err) } for _, flag := range fixture.Flags { - repo.SetFlag(flag) + repo.SetFlag(flag, false) } for _, segment := range fixture.Segments { - repo.SetSegment(segment) + repo.SetSegment(segment, false) } for _, testCase := range fixture.Tests { From dc1e01863cc67a433b18f95b0d86d7bd3b7a6831 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Tue, 4 Oct 2022 15:07:20 +0100 Subject: [PATCH 5/8] Change go get to go install --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index f7eb47c6..ef646ab4 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ $(GOPATH)/bin/gosec: $(GOPATH)/bin/oapi-codegen: @echo "🔘 Installing oapicodegen ... (`date '+%H:%M:%S'`)" - @go get github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.11.0 + @go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@v1.11.0 PHONY+= tools tools: $(GOPATH)/bin/golangci-lint $(GOPATH)/bin/golint $(GOPATH)/bin/gosec $(GOPATH)/bin/goimports $(GOPATH)/bin/oapi-codegen From 313c3979becfe127b145e9e083abeea3ee9479f2 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Tue, 4 Oct 2022 16:36:54 +0100 Subject: [PATCH 6/8] Update to use more recent ff-test-cases submodule --- tests/ff-test-cases | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/ff-test-cases b/tests/ff-test-cases index b79d82fd..6e782f1b 160000 --- a/tests/ff-test-cases +++ b/tests/ff-test-cases @@ -1 +1 @@ -Subproject commit b79d82fd5d80ef47a1c13e2e2bffd4a45a2e56b7 +Subproject commit 6e782f1b954f01feae622f707dbfef38a264476b From e2ee9ce134c962da3d4b417561d50735b5feb6e4 Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Tue, 4 Oct 2022 17:03:23 +0100 Subject: [PATCH 7/8] Pin version of Go lint as per https://github.com/golangci/golangci-lint-action/issues/535 --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index ef646ab4..39c254c1 100644 --- a/Makefile +++ b/Makefile @@ -78,7 +78,7 @@ sec: $(GOPATH)/bin/gosec $(GOPATH)/bin/golangci-lint: @echo "🔘 Installing golangci-lint... (`date '+%H:%M:%S'`)" - @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin + @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.47.3 $(GOPATH)/bin/golint: @echo "🔘 Installing golint ... (`date '+%H:%M:%S'`)" From 5014d3dd633ff794363996d88576d068aacd3eaa Mon Sep 17 00:00:00 2001 From: stephenmcconkey Date: Wed, 5 Oct 2022 10:40:12 +0100 Subject: [PATCH 8/8] Refactor if's --- client/client.go | 13 +++++++------ client/helpers_test.go | 4 +--- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/client/client.go b/client/client.go index daedcfa4..553c80c0 100644 --- a/client/client.go +++ b/client/client.go @@ -88,14 +88,15 @@ func NewCfClient(sdkKey string, options ...ConfigOption) (*CfClient, error) { } var err error + + lruCache, err := repository.NewLruCache(10000) + if err != nil { + return nil, err + } + client.repository = repository.New(lruCache) + if client.config != nil { client.repository = repository.New(config.Cache) - } else { - lruCache, err := repository.NewLruCache(10000) - if err != nil { - return nil, err - } - client.repository = repository.New(lruCache) } client.evaluator, err = evaluation.NewEvaluator(client.repository, client, config.Logger) diff --git a/client/helpers_test.go b/client/helpers_test.go index 4ce943ad..a2afb1c8 100644 --- a/client/helpers_test.go +++ b/client/helpers_test.go @@ -53,11 +53,9 @@ func MakeStringFeatureConfigs(name, defaultVariation, offVariation, state string // If there are any PreReqs then we need to store them as flags as well. for _, x := range preReqs { - var state string + state := "off" if x.Variations[0] == "true" { state = "on" - } else { - state = "off" } featureConfig = append(featureConfig, MakeBoolFeatureConfig(x.Feature, "true", "false", state, nil)) }