Skip to content

Commit ee18a11

Browse files
added example of profiling and benchmark testing
1 parent ea5c725 commit ee18a11

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

examples/main_profile_feature.go

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
// to run the CPU profiling: go build -ldflags "-X main.RunCPUProfile=true" main.go && ./main
2+
// to run the Mem profiling: go build -ldflags "-X main.RunMemProfile=true" main.go && ./main
3+
4+
package main
5+
6+
import (
7+
"encoding/json"
8+
"github.com/optimizely/go-sdk/optimizely/client"
9+
"github.com/optimizely/go-sdk/optimizely/decision"
10+
"github.com/optimizely/go-sdk/optimizely/entities"
11+
"github.com/optimizely/go-sdk/optimizely/notification"
12+
"io/ioutil"
13+
"log"
14+
"os"
15+
"path"
16+
17+
"github.com/pkg/profile"
18+
)
19+
20+
// stressTest has everything that test app has. it is used to run profile
21+
func stressTest() {
22+
/*
23+
For the test app, the biggest json file is used with 100 entities.
24+
DATAFILES_DIR has to be set to point to the path where 100_entities.json is located.
25+
*/
26+
type isFeatureEnabledRequestParams struct {
27+
FeatureKey string `json:"feature_flag_key"`
28+
UserID string `json:"user_id"`
29+
Attributes map[string]interface{} `json:"attributes"`
30+
}
31+
32+
type Context struct {
33+
CustomEventDispatcher string `json:"custom_event_dispatcher"`
34+
RequestID string `json:"request_id"`
35+
UserProfileService string `json:"user_profile_service"`
36+
Datafile string `json:"datafile"`
37+
DispatchedEvents []map[string]interface{} `json:"dispatched_events"`
38+
}
39+
40+
strBytes := []byte(` { "context": {
41+
"datafile": "100_entities.json",
42+
"custom_event_dispatcher": "ProxyEventDispatcher",
43+
"request_id": "4e3e37e3-c7ae-4cb6-bbb5-f6ef93c84d43",
44+
"user_profile_service": "NoOpService",
45+
"user_profiles": [],
46+
"with_listener": []
47+
},
48+
"user_id": "test_user_1",
49+
"feature_flag_key": "feature_5",
50+
"attributes": {
51+
"attr_5": "testvalue"
52+
}
53+
}`)
54+
55+
var params isFeatureEnabledRequestParams
56+
err := json.Unmarshal(strBytes, &params)
57+
if err != nil {
58+
log.Fatal(err)
59+
}
60+
61+
var requestBodyMap map[string]*json.RawMessage
62+
63+
err = json.Unmarshal(strBytes, &requestBodyMap)
64+
if err != nil {
65+
log.Fatal(err)
66+
}
67+
68+
var fscCtx Context
69+
err = json.Unmarshal(*requestBodyMap["context"], &fscCtx)
70+
if err != nil {
71+
log.Fatal(err)
72+
}
73+
74+
var datafileDir = path.Join(os.Getenv("DATAFILES_DIR"), fscCtx.Datafile)
75+
76+
datafile, err := ioutil.ReadFile(datafileDir)
77+
if err != nil {
78+
log.Fatal(err)
79+
}
80+
81+
optlyClient := &client.OptimizelyFactory{
82+
Datafile: datafile,
83+
}
84+
85+
user := entities.UserContext{
86+
ID: params.UserID,
87+
Attributes: params.Attributes,
88+
}
89+
90+
// Creates a default, canceleable context
91+
notificationCenter := notification.NewNotificationCenter()
92+
decisionService := decision.NewCompositeService(notificationCenter)
93+
94+
clientOptions := client.Options{
95+
DecisionService: decisionService,
96+
}
97+
clientApp, err := optlyClient.ClientWithOptions(clientOptions)
98+
if err != nil {
99+
log.Fatal(err)
100+
}
101+
102+
clientApp.IsFeatureEnabled(params.FeatureKey, user)
103+
}
104+
105+
var RunMemProfile = "false"
106+
var RunCPUProfile = "false"
107+
108+
func main() {
109+
110+
if RunMemProfile == "true" || RunCPUProfile == "true" {
111+
112+
const RUN_NUMBER = 50
113+
if RunMemProfile == "true" {
114+
defer profile.Start(profile.MemProfile, profile.ProfilePath("."), profile.MemProfileRate(1)).Stop()
115+
} else if RunCPUProfile == "true" {
116+
defer profile.Start(profile.CPUProfile, profile.ProfilePath(".")).Stop()
117+
}
118+
119+
for i := 0; i < RUN_NUMBER; i++ {
120+
stressTest()
121+
}
122+
}
123+
124+
}

0 commit comments

Comments
 (0)