@@ -32,35 +32,72 @@ import (
32
32
type OptimizelyFactory struct {
33
33
SDKKey string
34
34
Datafile []byte
35
+
36
+ configManager pkg.ProjectConfigManager
37
+ decisionService decision.Service
38
+ eventProcessor event.Processor
39
+ executionCtx utils.ExecutionCtx
40
+ userProfileService decision.UserProfileService
41
+ overrideStore decision.ExperimentOverrideStore
35
42
}
36
43
37
44
// OptionFunc is a type to a proper func
38
- type OptionFunc func (* OptimizelyClient )
45
+ type OptionFunc func (* OptimizelyFactory )
39
46
40
47
// Client gets client and sets some parameters
41
48
func (f OptimizelyFactory ) Client (clientOptions ... OptionFunc ) (* OptimizelyClient , error ) {
49
+ // extract options
50
+ for _ , opt := range clientOptions {
51
+ opt (& f )
52
+ }
42
53
43
- executionCtx := utils .NewCancelableExecutionCtx ()
54
+ if f .SDKKey == "" && f .Datafile == nil && f .configManager == nil {
55
+ return nil , errors .New ("unable to instantiate client: no project config manager, SDK key, or a Datafile provided" )
56
+ }
44
57
45
- appClient := & OptimizelyClient {
46
- executionCtx : executionCtx ,
47
- DecisionService : decision .NewCompositeService (f .SDKKey ),
48
- EventProcessor : event .NewBatchEventProcessor (event .WithBatchSize (event .DefaultBatchSize ),
49
- event .WithQueueSize (event .DefaultEventQueueSize ), event .WithFlushInterval (event .DefaultEventFlushInterval ),
50
- event .WithSDKKey (f .SDKKey )),
58
+ var executionCtx utils.ExecutionCtx
59
+ if f .executionCtx != nil {
60
+ executionCtx = f .executionCtx
61
+ } else {
62
+ executionCtx = utils .NewCancelableExecutionCtx ()
51
63
}
52
64
53
- for _ , opt := range clientOptions {
54
- opt (appClient )
65
+ appClient := & OptimizelyClient {executionCtx : executionCtx }
66
+
67
+ if f .configManager != nil {
68
+ appClient .ConfigManager = f .configManager
69
+ } else {
70
+ appClient .ConfigManager = config .NewPollingProjectConfigManager (
71
+ f .SDKKey ,
72
+ config .InitialDatafile (f .Datafile ),
73
+ config .PollingInterval (config .DefaultPollingInterval ),
74
+ )
55
75
}
56
76
57
- if f .SDKKey == "" && f .Datafile == nil && appClient .ConfigManager == nil {
58
- return nil , errors .New ("unable to instantiate client: no project config manager, SDK key, or a Datafile provided" )
77
+ if f .eventProcessor != nil {
78
+ appClient .EventProcessor = f .eventProcessor
79
+ } else {
80
+ appClient .EventProcessor = event .NewBatchEventProcessor (
81
+ event .WithBatchSize (event .DefaultBatchSize ),
82
+ event .WithQueueSize (event .DefaultEventQueueSize ),
83
+ event .WithFlushInterval (event .DefaultEventFlushInterval ),
84
+ event .WithSDKKey (f .SDKKey ),
85
+ )
59
86
}
60
87
61
- if appClient .ConfigManager == nil { // if it was not passed then assign here
62
- appClient .ConfigManager = config .NewPollingProjectConfigManager (f .SDKKey ,
63
- config .InitialDatafile (f .Datafile ), config .PollingInterval (config .DefaultPollingInterval ))
88
+ if f .decisionService != nil {
89
+ appClient .DecisionService = f .decisionService
90
+ } else {
91
+ experimentServiceOptions := []decision.CESOptionFunc {}
92
+ if f .userProfileService != nil {
93
+ experimentServiceOptions = append (experimentServiceOptions , decision .WithUserProfileService (f .userProfileService ))
94
+ }
95
+ if f .overrideStore != nil {
96
+ experimentServiceOptions = append (experimentServiceOptions , decision .WithOverrideStore (f .overrideStore ))
97
+ }
98
+ compositeExperimentService := decision .NewCompositeExperimentService (experimentServiceOptions ... )
99
+ compositeService := decision .NewCompositeService (f .SDKKey , decision .WithCompositeExperimentService (compositeExperimentService ))
100
+ appClient .DecisionService = compositeService
64
101
}
65
102
66
103
// Initialize the default services with the execution context
@@ -77,59 +114,73 @@ func (f OptimizelyFactory) Client(clientOptions ...OptionFunc) (*OptimizelyClien
77
114
78
115
// WithPollingConfigManager sets polling config manager on a client
79
116
func WithPollingConfigManager (sdkKey string , pollingInterval time.Duration , initDataFile []byte ) OptionFunc {
80
- return func (f * OptimizelyClient ) {
81
- f .ConfigManager = config .NewPollingProjectConfigManager (sdkKey , config .InitialDatafile (initDataFile ),
117
+ return func (f * OptimizelyFactory ) {
118
+ f .configManager = config .NewPollingProjectConfigManager (sdkKey , config .InitialDatafile (initDataFile ),
82
119
config .PollingInterval (pollingInterval ))
83
120
}
84
121
}
85
122
86
123
// WithPollingConfigManagerRequester sets polling config manager on a client
87
124
func WithPollingConfigManagerRequester (requester utils.Requester , pollingInterval time.Duration , initDataFile []byte ) OptionFunc {
88
- return func (f * OptimizelyClient ) {
89
- f .ConfigManager = config .NewPollingProjectConfigManager ("" , config .InitialDatafile (initDataFile ),
125
+ return func (f * OptimizelyFactory ) {
126
+ f .configManager = config .NewPollingProjectConfigManager ("" , config .InitialDatafile (initDataFile ),
90
127
config .PollingInterval (pollingInterval ), config .Requester (requester ))
91
128
}
92
129
}
93
130
94
131
// WithConfigManager sets polling config manager on a client
95
132
func WithConfigManager (configManager pkg.ProjectConfigManager ) OptionFunc {
96
- return func (f * OptimizelyClient ) {
97
- f .ConfigManager = configManager
133
+ return func (f * OptimizelyFactory ) {
134
+ f .configManager = configManager
98
135
}
99
136
}
100
137
101
138
// WithCompositeDecisionService sets decision service on a client
102
139
func WithCompositeDecisionService (sdkKey string ) OptionFunc {
103
- return func (f * OptimizelyClient ) {
104
- f .DecisionService = decision .NewCompositeService (sdkKey )
140
+ return func (f * OptimizelyFactory ) {
141
+ f .decisionService = decision .NewCompositeService (sdkKey )
105
142
}
106
143
}
107
144
108
145
// WithDecisionService sets decision service on a client
109
146
func WithDecisionService (decisionService decision.Service ) OptionFunc {
110
- return func (f * OptimizelyClient ) {
111
- f .DecisionService = decisionService
147
+ return func (f * OptimizelyFactory ) {
148
+ f .decisionService = decisionService
149
+ }
150
+ }
151
+
152
+ // WithUserProfileService sets the user profile service on the decision service
153
+ func WithUserProfileService (userProfileService decision.UserProfileService ) OptionFunc {
154
+ return func (f * OptimizelyFactory ) {
155
+ f .userProfileService = userProfileService
156
+ }
157
+ }
158
+
159
+ // WithExperimentOverrides sets the experiment override store on the decision service
160
+ func WithExperimentOverrides (overrideStore decision.ExperimentOverrideStore ) OptionFunc {
161
+ return func (f * OptimizelyFactory ) {
162
+ f .overrideStore = overrideStore
112
163
}
113
164
}
114
165
115
166
// WithBatchEventProcessor sets event processor on a client
116
167
func WithBatchEventProcessor (batchSize , queueSize int , flushInterval time.Duration ) OptionFunc {
117
- return func (f * OptimizelyClient ) {
118
- f .EventProcessor = event .NewBatchEventProcessor (event .WithBatchSize (batchSize ),
168
+ return func (f * OptimizelyFactory ) {
169
+ f .eventProcessor = event .NewBatchEventProcessor (event .WithBatchSize (batchSize ),
119
170
event .WithQueueSize (queueSize ), event .WithFlushInterval (flushInterval ))
120
171
}
121
172
}
122
173
123
174
// WithEventProcessor sets event processor on a client
124
175
func WithEventProcessor (eventProcessor event.Processor ) OptionFunc {
125
- return func (f * OptimizelyClient ) {
126
- f .EventProcessor = eventProcessor
176
+ return func (f * OptimizelyFactory ) {
177
+ f .eventProcessor = eventProcessor
127
178
}
128
179
}
129
180
130
181
// WithExecutionContext allows user to pass in their own execution context to override the default one in the client
131
182
func WithExecutionContext (executionContext utils.ExecutionCtx ) OptionFunc {
132
- return func (f * OptimizelyClient ) {
183
+ return func (f * OptimizelyFactory ) {
133
184
f .executionCtx = executionContext
134
185
}
135
186
}
0 commit comments