Skip to content

Commit 815d529

Browse files
authored
sdk configs (#251)
1 parent 3e890c8 commit 815d529

File tree

6 files changed

+119
-21
lines changed

6 files changed

+119
-21
lines changed

evaluator.go

-21
Original file line numberDiff line numberDiff line change
@@ -823,27 +823,6 @@ func removeEmptyStrings(s []string) []string {
823823
return r
824824
}
825825

826-
func getNumericValue(a interface{}) (float64, bool) {
827-
if a == nil {
828-
return 0, false
829-
}
830-
aVal := reflect.ValueOf(a)
831-
switch reflect.TypeOf(a).Kind() {
832-
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
833-
return float64(aVal.Int()), true
834-
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
835-
return float64(aVal.Uint()), true
836-
case reflect.Float32, reflect.Float64:
837-
return float64(aVal.Float()), true
838-
case reflect.String:
839-
f, err := strconv.ParseFloat(aVal.String(), 64)
840-
if err == nil {
841-
return f, true
842-
}
843-
}
844-
return 0, false
845-
}
846-
847826
func castToString(a interface{}) string {
848827
asString, ok := a.(string)
849828
if !ok {

global_state.go

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
// Instead, define an accessor below using the Mutex lock
1111
type GlobalState struct {
1212
logger *OutputLogger
13+
sdkConfig *SDKConfigs
1314
sessionID string
1415
mu sync.RWMutex
1516
}
@@ -41,3 +42,15 @@ func InitializeGlobalSessionID() {
4142
defer global.mu.Unlock()
4243
global.sessionID = uuid.NewString()
4344
}
45+
46+
func SDKConfig() *SDKConfigs {
47+
global.mu.RLock()
48+
defer global.mu.RUnlock()
49+
return global.sdkConfig
50+
}
51+
52+
func InitializeGlobalSDKConfig() {
53+
global.mu.Lock()
54+
defer global.mu.Unlock()
55+
global.sdkConfig = &SDKConfigs{}
56+
}

sdk_configs.go

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package statsig
2+
3+
import (
4+
"strconv"
5+
"sync"
6+
)
7+
8+
type SDKConfigs struct {
9+
flags map[string]bool
10+
configs map[string]interface{}
11+
mu sync.RWMutex
12+
}
13+
14+
func (s *SDKConfigs) SetFlags(newFlags map[string]bool) {
15+
s.mu.Lock()
16+
s.flags = newFlags
17+
s.mu.Unlock()
18+
}
19+
20+
func (s *SDKConfigs) SetConfigs(newConfigs map[string]interface{}) {
21+
s.mu.Lock()
22+
s.configs = newConfigs
23+
s.mu.Unlock()
24+
}
25+
26+
func (s *SDKConfigs) On(key string) (bool, bool) {
27+
s.mu.RLock()
28+
defer s.mu.RUnlock()
29+
val, exists := s.flags[key]
30+
return val, exists
31+
}
32+
33+
func (s *SDKConfigs) GetConfigNumValue(config string) (float64, bool) {
34+
s.mu.RLock()
35+
defer s.mu.RUnlock()
36+
value, exists := s.configs[config]
37+
if !exists {
38+
return 0, false
39+
}
40+
41+
return getNumericValue(value)
42+
}
43+
44+
func (s *SDKConfigs) GetConfigIntValue(config string) (int, bool) {
45+
s.mu.RLock()
46+
defer s.mu.RUnlock()
47+
value, exists := s.configs[config]
48+
if !exists {
49+
return 0, false
50+
}
51+
52+
switch v := value.(type) {
53+
case int:
54+
return v, true
55+
case float64:
56+
return int(v), true
57+
default:
58+
return 0, false
59+
}
60+
}
61+
62+
func (s *SDKConfigs) GetConfigStrValue(config string) (string, bool) {
63+
s.mu.RLock()
64+
defer s.mu.RUnlock()
65+
value, exists := s.configs[config]
66+
if !exists {
67+
return "", false
68+
}
69+
70+
switch v := value.(type) {
71+
case string:
72+
return v, true
73+
case int:
74+
return strconv.Itoa(v), true
75+
case float64:
76+
return strconv.FormatFloat(v, 'f', -1, 64), true
77+
default:
78+
return "", false
79+
}
80+
}

statsig.go

+1
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ func Initialize(sdkKey string) InitializeDetails {
110110
func InitializeWithOptions(sdkKey string, options *Options) InitializeDetails {
111111
InitializeGlobalOutputLogger(options.OutputLoggerOptions)
112112
InitializeGlobalSessionID()
113+
InitializeGlobalSDKConfig()
113114
if IsInitialized() {
114115
Logger().Log("Statsig is already initialized.", nil)
115116
return InitializeDetails{Success: true, Source: instance.evaluator.store.source}

store.go

+3
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ type downloadConfigSpecResponse struct {
8282
HashedSDKKeysToEntities map[string]configEntities `json:"hashed_sdk_keys_to_entities,omitempty"`
8383
HashedSDKKeyUsed string `json:"hashed_sdk_key_used,omitempty"`
8484
SDKFlags map[string]bool `json:"sdk_flags,omitempty"`
85+
SDKConfigs map[string]interface{} `json:"sdk_configs,omitempty"`
8586
}
8687

8788
type configEntities struct {
@@ -468,6 +469,8 @@ func (s *store) setConfigSpecs(specs downloadConfigSpecResponse) (bool, bool) {
468469
}
469470
}
470471

472+
SDKConfig().SetConfigs(specs.SDKConfigs)
473+
SDKConfig().SetFlags(specs.SDKFlags)
471474
s.mu.Lock()
472475
s.featureGates = newGates
473476
s.dynamicConfigs = newConfigs

util.go

+22
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding/binary"
77
"encoding/json"
88
"errors"
9+
"reflect"
910
"strconv"
1011
"testing"
1112
"time"
@@ -126,3 +127,24 @@ func hashName(hashAlgorithm string, name string) string {
126127
return name
127128
}
128129
}
130+
131+
func getNumericValue(a interface{}) (float64, bool) {
132+
if a == nil {
133+
return 0, false
134+
}
135+
aVal := reflect.ValueOf(a)
136+
switch reflect.TypeOf(a).Kind() {
137+
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
138+
return float64(aVal.Int()), true
139+
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
140+
return float64(aVal.Uint()), true
141+
case reflect.Float32, reflect.Float64:
142+
return float64(aVal.Float()), true
143+
case reflect.String:
144+
f, err := strconv.ParseFloat(aVal.String(), 64)
145+
if err == nil {
146+
return f, true
147+
}
148+
}
149+
return 0, false
150+
}

0 commit comments

Comments
 (0)