Skip to content

Commit

Permalink
Move SDK handling behind a service
Browse files Browse the repository at this point in the history
  • Loading branch information
z4kn4fein committed Mar 24, 2024
1 parent bfa18f2 commit e8892f1
Show file tree
Hide file tree
Showing 38 changed files with 496 additions and 388 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.21-alpine3.18 AS build
FROM golang:1.22.1-alpine3.19 AS build

WORKDIR /go/src/configcat_proxy

Expand Down
9 changes: 7 additions & 2 deletions diag/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ func TestNewServer(t *testing.T) {
Status: config.StatusConfig{Enabled: true},
Metrics: config.MetricsConfig{Enabled: true},
}
srv := NewServer(&conf, status.NewReporter(&config.Config{SDKs: map[string]*config.SDKConfig{"sdk": {Key: "key"}}}), metrics.NewReporter(), log.NewNullLogger(), errChan)

reporter := status.NewEmptyReporter()
reporter.RegisterSdk("test", &config.SDKConfig{Key: "key"})
srv := NewServer(&conf, reporter, metrics.NewReporter(), log.NewNullLogger(), errChan)
srv.Listen()
time.Sleep(500 * time.Millisecond)

Expand Down Expand Up @@ -47,7 +50,9 @@ func TestNewServer_NotEnabled(t *testing.T) {
Metrics: config.MetricsConfig{Enabled: false},
}

srv := NewServer(&conf, status.NewReporter(&config.Config{SDKs: map[string]*config.SDKConfig{"sdk": {Key: "key"}}}), metrics.NewReporter(), log.NewNullLogger(), errChan)
reporter := status.NewEmptyReporter()
reporter.RegisterSdk("test", &config.SDKConfig{Key: "key"})
srv := NewServer(&conf, reporter, metrics.NewReporter(), log.NewNullLogger(), errChan)
srv.Listen()
time.Sleep(500 * time.Millisecond)

Expand Down
9 changes: 6 additions & 3 deletions diag/status/mware_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import (

func TestInterceptSdk(t *testing.T) {
t.Run("ok", func(t *testing.T) {
reporter := NewReporter(&config.Config{SDKs: map[string]*config.SDKConfig{"test": {}}}).(*reporter)
reporter := NewEmptyReporter().(*reporter)
reporter.RegisterSdk("test", &config.SDKConfig{Key: "key"})
repSrv := httptest.NewServer(reporter.HttpHandler())
h := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusOK)
Expand All @@ -33,7 +34,8 @@ func TestInterceptSdk(t *testing.T) {
assert.Equal(t, 0, len(stat.Cache.Records))
})
t.Run("not modified", func(t *testing.T) {
reporter := NewReporter(&config.Config{SDKs: map[string]*config.SDKConfig{"test": {}}}).(*reporter)
reporter := NewEmptyReporter().(*reporter)
reporter.RegisterSdk("test", &config.SDKConfig{Key: "key"})
repSrv := httptest.NewServer(reporter.HttpHandler())
h := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusNotModified)
Expand All @@ -56,7 +58,8 @@ func TestInterceptSdk(t *testing.T) {
assert.Equal(t, 0, len(stat.Cache.Records))
})
t.Run("error", func(t *testing.T) {
reporter := NewReporter(&config.Config{SDKs: map[string]*config.SDKConfig{"test": {}}}).(*reporter)
reporter := NewEmptyReporter().(*reporter)
reporter.RegisterSdk("test", &config.SDKConfig{Key: "key"})
repSrv := httptest.NewServer(reporter.HttpHandler())
h := http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
writer.WriteHeader(http.StatusBadRequest)
Expand Down
94 changes: 53 additions & 41 deletions diag/status/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const maxRecordCount = 5
const maxLastErrorsMeaningDegraded = 2

type Reporter interface {
RegisterSdk(sdkId string, conf *config.SDKConfig)
ReportOk(component string, message string)
ReportError(component string, message string)
GetStatus() Status
Expand Down Expand Up @@ -74,14 +75,14 @@ type reporter struct {
records map[string][]record
mu sync.RWMutex
status Status
conf *config.Config
conf *config.CacheConfig
}

func NewNullReporter() Reporter {
return &reporter{records: make(map[string][]record), conf: &config.Config{SDKs: map[string]*config.SDKConfig{}}}
func NewEmptyReporter() Reporter {
return NewReporter(&config.CacheConfig{})
}

func NewReporter(conf *config.Config) Reporter {
func NewReporter(conf *config.CacheConfig) Reporter {
r := &reporter{
conf: conf,
records: make(map[string][]record),
Expand All @@ -90,44 +91,54 @@ func NewReporter(conf *config.Config) Reporter {
Cache: CacheStatus{
Status: Initializing,
},
SDKs: map[string]*SdkStatus{},
},
}
r.status.SDKs = make(map[string]*SdkStatus, len(conf.SDKs))
for key, sdk := range conf.SDKs {
status := &SdkStatus{
Mode: Online,
SdkKey: utils.Obfuscate(sdk.Key, 5),
Source: SdkSourceStatus{
Type: RemoteSrc,
Status: Initializing,
},
}
r.status.SDKs[key] = status
if sdk.Offline.Enabled {
status.Mode = Offline
if sdk.Offline.Local.FilePath != "" {
status.Source.Type = FileSrc
r.status.Cache.Status = NA
} else {
status.Source.Type = CacheSrc
}
}
if !conf.Cache.IsSet() {
return r
}

func (r *reporter) RegisterSdk(sdkId string, conf *config.SDKConfig) {
r.mu.Lock()
defer r.mu.Unlock()

status := &SdkStatus{
Mode: Online,
SdkKey: utils.Obfuscate(conf.Key, 5),
Source: SdkSourceStatus{
Type: RemoteSrc,
Status: Initializing,
},
}
r.status.SDKs[sdkId] = status
if conf.Offline.Enabled {
status.Mode = Offline
if conf.Offline.Local.FilePath != "" {
status.Source.Type = FileSrc
r.status.Cache.Status = NA
if status.Source.Type == CacheSrc {
r.ReportError(key, "cache offline source enabled without a configured cache")
}
} else {
status.Source.Type = CacheSrc
}
}
if !r.conf.IsSet() {
r.status.Cache.Status = NA
if status.Source.Type == CacheSrc {
r.appendRecord(sdkId, "cache offline source enabled without a configured cache", true)
}
}
return r
}

func (r *reporter) ReportOk(component string, message string) {
r.appendRecord(component, "[ok] "+message, false)
r.mu.Lock()
defer r.mu.Unlock()

r.appendRecord(component, message, false)
}

func (r *reporter) ReportError(component string, message string) {
r.appendRecord(component, "[error] "+message, true)
r.mu.Lock()
defer r.mu.Unlock()

r.appendRecord(component, message, true)
}

func (r *reporter) HttpHandler() http.HandlerFunc {
Expand Down Expand Up @@ -169,8 +180,11 @@ func (r *reporter) checkStatus(records []record) ([]string, HealthStatus) {
}

func (r *reporter) appendRecord(component string, message string, isError bool) {
r.mu.Lock()
defer r.mu.Unlock()
if isError {
message = "[error] " + message
} else {
message = "[ok] " + message
}

recs, ok := r.records[component]
if !ok {
Expand All @@ -194,14 +208,12 @@ func (r *reporter) appendRecord(component string, message string, isError bool)

allSdksDown := true
hasDegradedSdk := false
for key := range r.conf.SDKs {
if sdk, ok := r.status.SDKs[key]; ok {
if sdk.Source.Status != Down {
allSdksDown = false
}
if sdk.Source.Status != Healthy {
hasDegradedSdk = true
}
for _, sdk := range r.status.SDKs {
if sdk.Source.Status != Down {
allSdksDown = false
}
if sdk.Source.Status != Healthy {
hasDegradedSdk = true
}
}
if !hasDegradedSdk && !allSdksDown {
Expand Down
Loading

0 comments on commit e8892f1

Please sign in to comment.