Skip to content

Commit a4fe3ae

Browse files
committed
feat: Introduce statsig package from SDK along with config
1 parent c1c0d00 commit a4fe3ae

File tree

6 files changed

+141
-0
lines changed

6 files changed

+141
-0
lines changed

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ require (
2525
github.com/rs/cors v1.7.0
2626
github.com/sirupsen/logrus v1.9.3
2727
github.com/spf13/viper v1.10.1
28+
github.com/statsig-io/go-sdk v1.26.0
2829
github.com/stretchr/testify v1.8.4
2930
github.com/twmb/franz-go v1.17.0
3031
github.com/twmb/franz-go/pkg/kmsg v1.8.0
@@ -99,8 +100,10 @@ require (
99100
github.com/spf13/cast v1.4.1 // indirect
100101
github.com/spf13/jwalterweatherman v1.1.0 // indirect
101102
github.com/spf13/pflag v1.0.5 // indirect
103+
github.com/statsig-io/ip3country-go v0.2.0 // indirect
102104
github.com/subosito/gotenv v1.2.0 // indirect
103105
github.com/tinylib/msgp v1.1.8 // indirect
106+
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f // indirect
104107
go.uber.org/atomic v1.11.0 // indirect
105108
golang.org/x/mod v0.12.0 // indirect
106109
golang.org/x/net v0.20.0 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,6 +1909,10 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y
19091909
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
19101910
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
19111911
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
1912+
github.com/statsig-io/go-sdk v1.26.0 h1:HaPwN1+mDFdCnvqDbo8cr3obIlqmrShR9J2ogxw3kZs=
1913+
github.com/statsig-io/go-sdk v1.26.0/go.mod h1:Pej0D6R75gTHj7FdS6pbXQ7ayF0HL1cwOgiz5zDNdyc=
1914+
github.com/statsig-io/ip3country-go v0.2.0 h1:4z4ovVCx7GnQAKJC753bjcOgxLQJFsrDdcCKda4I2U8=
1915+
github.com/statsig-io/ip3country-go v0.2.0/go.mod h1:PKuA/VSpe4puBXw3BNGAHyP8IOZOiXAh/xIz+iYYoMQ=
19121916
github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8=
19131917
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
19141918
github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -1961,6 +1965,8 @@ github.com/twmb/franz-go v1.17.0 h1:hawgCx5ejDHkLe6IwAtFWwxi3OU4OztSTl7ZV5rwkYk=
19611965
github.com/twmb/franz-go v1.17.0/go.mod h1:NreRdJ2F7dziDY/m6VyspWd6sNxHKXdMZI42UfQ3GXM=
19621966
github.com/twmb/franz-go/pkg/kmsg v1.8.0 h1:lAQB9Z3aMrIP9qF9288XcFf/ccaSxEitNA1CDTEIeTA=
19631967
github.com/twmb/franz-go/pkg/kmsg v1.8.0/go.mod h1:HzYEb8G3uu5XevZbtU0dVbkphaKTHk0X68N5ka4q6mU=
1968+
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f h1:A+MmlgpvrHLeUP8dkBVn4Pnf5Bp5Yk2OALm7SEJLLE8=
1969+
github.com/ua-parser/uap-go v0.0.0-20211112212520-00c877edfe0f/go.mod h1:OBcG9bn7sHtXgarhUEb3OfCnNsgtGnkVf41ilSZ3K3E=
19641970
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
19651971
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
19661972
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=

pkg/configuration/configuration.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
logger "github.com/scribd/go-sdk/pkg/logger"
1212
"github.com/scribd/go-sdk/pkg/pubsub"
1313
server "github.com/scribd/go-sdk/pkg/server"
14+
"github.com/scribd/go-sdk/pkg/statsig"
1415
tracking "github.com/scribd/go-sdk/pkg/tracking"
1516
)
1617

@@ -25,6 +26,7 @@ type Config struct {
2526
PubSub *pubsub.Config
2627
Cache *cache.Config
2728
AWS *aws.Config
29+
Statsig *statsig.Config
2830
}
2931

3032
// NewConfig returns a new Config instance
@@ -77,6 +79,11 @@ func NewConfig() (*Config, error) {
7779
errGroup = wrapErrors(errGroup, fmt.Errorf("aws config err: %w", err))
7880
}
7981

82+
statsigConfig, err := statsig.NewConfig()
83+
if err != nil {
84+
errGroup = wrapErrors(errGroup, fmt.Errorf("statsig config err: %w", err))
85+
}
86+
8087
config.App = appConfig
8188
config.Database = dbConfig
8289
config.Instrumentation = instrumentationConfig
@@ -86,6 +93,7 @@ func NewConfig() (*Config, error) {
8693
config.PubSub = pubsubConfig
8794
config.Cache = cacheConfig
8895
config.AWS = awsConfig
96+
config.Statsig = statsigConfig
8997

9098
return config, errGroup
9199
}

pkg/statsig/config.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package statsig
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"time"
7+
8+
cbuilder "github.com/scribd/go-sdk/internal/pkg/configuration/builder"
9+
)
10+
11+
// Config stores the configuration for the statsig.
12+
type Config struct {
13+
SecretKey string `mapstructure:"secret_key"`
14+
LocalMode bool `mapstructure:"local_mode"`
15+
ConfigSyncInterval time.Duration `mapstructure:"config_sync_interval"`
16+
IDListSyncInterval time.Duration `mapstructure:"id_list_sync_interval"`
17+
18+
environment string
19+
}
20+
21+
// NewConfig returns a new StatsigConfig instance.
22+
func NewConfig() (*Config, error) {
23+
config := &Config{}
24+
config.environment = os.Getenv("APP_ENV")
25+
26+
viperBuilder := cbuilder.New("statsig")
27+
28+
vConf, err := viperBuilder.Build()
29+
if err != nil {
30+
return config, err
31+
}
32+
33+
if err = vConf.Unmarshal(config); err != nil {
34+
return config, fmt.Errorf("unable to decode into struct: %s", err.Error())
35+
}
36+
37+
return config, nil
38+
}

pkg/statsig/config_test.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package statsig
2+
3+
import (
4+
"os"
5+
"testing"
6+
"time"
7+
8+
assert "github.com/stretchr/testify/assert"
9+
)
10+
11+
func TestNewConfig(t *testing.T) {
12+
t.Run("RunningInTestEnvironment", func(t *testing.T) {
13+
expected := "test"
14+
actual := os.Getenv("APP_ENV")
15+
assert.Equal(t, expected, actual)
16+
})
17+
18+
testCases := []struct {
19+
name string
20+
secretKey string
21+
localMode bool
22+
configSyncInterval time.Duration
23+
idListSyncInterval time.Duration
24+
wantError bool
25+
}{
26+
{
27+
name: "default",
28+
secretKey: "",
29+
localMode: false,
30+
configSyncInterval: 0,
31+
idListSyncInterval: 0,
32+
wantError: true,
33+
},
34+
}
35+
36+
for _, tc := range testCases {
37+
t.Run(tc.name, func(t *testing.T) {
38+
c, err := NewConfig()
39+
if tc.wantError {
40+
assert.Error(t, err)
41+
}
42+
43+
assert.Equal(t, c.SecretKey, tc.secretKey)
44+
assert.Equal(t, c.LocalMode, tc.localMode)
45+
assert.Equal(t, c.ConfigSyncInterval, tc.configSyncInterval)
46+
assert.Equal(t, c.IDListSyncInterval, tc.idListSyncInterval)
47+
})
48+
}
49+
}

pkg/statsig/statsig.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package statsig
2+
3+
import (
4+
statsig "github.com/statsig-io/go-sdk"
5+
)
6+
7+
func Initialize(c *Config) {
8+
opts := &statsig.Options{
9+
Environment: statsig.Environment{Tier: c.environment},
10+
}
11+
12+
if c.LocalMode {
13+
opts.LocalMode = true
14+
}
15+
16+
if c.ConfigSyncInterval > 0 {
17+
opts.ConfigSyncInterval = c.ConfigSyncInterval
18+
}
19+
20+
if c.IDListSyncInterval > 0 {
21+
opts.IDListSyncInterval = c.IDListSyncInterval
22+
}
23+
24+
statsig.InitializeWithOptions(c.SecretKey, opts)
25+
}
26+
27+
func GetExperiment(user statsig.User, experiment string) statsig.DynamicConfig {
28+
return statsig.GetExperiment(user, experiment)
29+
}
30+
31+
func GetFeatureFlag(user statsig.User, flag string) statsig.FeatureGate {
32+
return statsig.GetGate(user, flag)
33+
}
34+
35+
func Shutdown() {
36+
statsig.Shutdown()
37+
}

0 commit comments

Comments
 (0)