Skip to content

Commit 1c35f5d

Browse files
Merge pull request #119 from optimizely/pawel/OASIS-5380
refactor initialization part of optimizely client and polling manager
2 parents 2fba187 + cbe02b3 commit 1c35f5d

File tree

6 files changed

+117
-191
lines changed

6 files changed

+117
-191
lines changed

examples/benchmark/main.go

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,7 @@ func stressTest() {
4444
notificationCenter := notification.NewNotificationCenter()
4545
decisionService := decision.NewCompositeService(notificationCenter)
4646

47-
clientOptions := client.Options{
48-
DecisionService: decisionService,
49-
}
50-
clientApp, err := optlyClient.ClientWithOptions(clientOptions)
47+
clientApp, err := optlyClient.Client(client.DecisionService(decisionService))
5148
if err != nil {
5249
log.Print(err)
5350
}

examples/main.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,44 +30,44 @@ func main() {
3030

3131
/************* StaticClient ********************/
3232

33-
app, err := optimizelyFactory.StaticClient()
33+
optimizelyClient, err := optimizelyFactory.StaticClient()
3434

3535
if err != nil {
3636
fmt.Printf("Error instantiating client: %s", err)
3737
return
3838
}
3939

40-
enabled, _ := app.IsFeatureEnabled("mutext_feat", user)
40+
enabled, _ := optimizelyClient.IsFeatureEnabled("mutext_feat", user)
4141
fmt.Printf("Is feature enabled? %v\n", enabled)
4242

4343
fmt.Println()
44-
app.Close() // user can close dispatcher
44+
optimizelyClient.Close() // user can close dispatcher
4545
fmt.Println()
4646
/************* Client ********************/
4747

4848
optimizelyFactory = &client.OptimizelyFactory{
4949
SDKKey: "4SLpaJA1r1pgE6T2CoMs9q",
5050
}
5151

52-
app, err = optimizelyFactory.Client()
52+
optimizelyClient, err = optimizelyFactory.Client()
5353

5454
if err != nil {
5555
fmt.Printf("Error instantiating client: %s", err)
5656
return
5757
}
5858

59-
enabled, _ = app.IsFeatureEnabled("mutext_feat", user)
59+
enabled, _ = optimizelyClient.IsFeatureEnabled("mutext_feat", user)
6060
fmt.Printf("Is feature enabled? %v\n", enabled)
61-
app.Close() // user can close dispatcher
61+
optimizelyClient.Close() // user can close dispatcher
6262

6363
/************* Setting Polling Interval ********************/
6464

6565
notificationCenter := notification.NewNotificationCenter()
6666

67-
app = optimizelyFactory.GetClient(
68-
client.PollingConfigManager("4SLpaJA1r1pgE6T2CoMs9q", time.Second, nil),
67+
optimizelyClient, _ = optimizelyFactory.Client(
68+
client.PollingConfigManager("4SLpaJA1r1pgE6T2CoMs9q", time.Second, nil, notificationCenter),
6969
client.CompositeDecisionService(notificationCenter),
7070
client.BatchEventProcessor(event.DefaultBatchSize, event.DefaultEventQueueSize, event.DefaultEventFlushInterval),
7171
)
72-
app.Close()
72+
optimizelyClient.Close()
7373
}

optimizely/client/factory.go

Lines changed: 30 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ import (
2929
"github.com/optimizely/go-sdk/optimizely/utils"
3030
)
3131

32-
// Options are used to create an instance of the OptimizelyClient with custom configuration
33-
type Options struct {
34-
ProjectConfigManager optimizely.ProjectConfigManager
35-
DecisionService decision.Service
36-
EventProcessor event.Processor
37-
}
38-
3932
// OptimizelyFactory is used to construct an instance of the OptimizelyClient
4033
type OptimizelyFactory struct {
4134
SDKKey string
@@ -45,26 +38,40 @@ type OptimizelyFactory struct {
4538
// OptionFunc is a type to a proper func
4639
type OptionFunc func(*OptimizelyClient, utils.ExecutionCtx)
4740

48-
// GetClient gets client and sets some parameters
49-
func (f OptimizelyFactory) GetClient(clientOptions ...OptionFunc) *OptimizelyClient {
41+
// Client gets client and sets some parameters
42+
func (f OptimizelyFactory) Client(clientOptions ...OptionFunc) (*OptimizelyClient, error) {
43+
5044
executionCtx := utils.NewCancelableExecutionCtx()
45+
notificationCenter := notification.NewNotificationCenter()
46+
5147
appClient := &OptimizelyClient{
52-
executionCtx: executionCtx,
48+
executionCtx: executionCtx,
49+
decisionService: decision.NewCompositeService(notificationCenter),
50+
eventProcessor: event.NewEventProcessor(executionCtx, event.DefaultBatchSize, event.DefaultEventQueueSize, event.DefaultEventFlushInterval),
5351
}
52+
5453
for _, opt := range clientOptions {
5554
opt(appClient, executionCtx)
5655
}
57-
return appClient
56+
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")
59+
}
60+
61+
if appClient.configManager == nil { // if it was not passed then assign here
62+
63+
appClient.configManager = config.NewPollingProjectConfigManager(executionCtx, f.SDKKey,
64+
config.InitialDatafile(f.Datafile), config.PollingInterval(config.DefaultPollingInterval), config.NotificationCenter(notificationCenter))
65+
}
66+
67+
return appClient, nil
5868
}
5969

6070
// PollingConfigManager sets polling config manager on a client
61-
func PollingConfigManager(sdkKey string, pollingInterval time.Duration, dataFile []byte) OptionFunc {
71+
func PollingConfigManager(sdkKey string, pollingInterval time.Duration, initDataFile []byte, notificationCenter notification.Center) OptionFunc {
6272
return func(f *OptimizelyClient, executionCtx utils.ExecutionCtx) {
63-
options := config.PollingProjectConfigManagerOptions{
64-
Datafile: dataFile,
65-
PollingInterval: pollingInterval,
66-
}
67-
f.configManager = config.NewPollingProjectConfigManagerWithOptions(f.executionCtx, sdkKey, options)
73+
f.configManager = config.NewPollingProjectConfigManager(f.executionCtx, sdkKey, config.InitialDatafile(initDataFile),
74+
config.PollingInterval(pollingInterval), config.NotificationCenter(notificationCenter))
6875
}
6976
}
7077

@@ -126,57 +133,12 @@ func (f OptimizelyFactory) StaticClient() (*OptimizelyClient, error) {
126133
configManager = staticConfigManager
127134
}
128135

129-
clientOptions := Options{
130-
ProjectConfigManager: configManager,
131-
}
132-
client, err := f.ClientWithOptions(clientOptions)
133-
return client, err
134-
}
135-
136-
// ClientWithOptions returns a client initialized with the given configuration options
137-
func (f OptimizelyFactory) ClientWithOptions(clientOptions Options) (*OptimizelyClient, error) {
138-
139-
executionCtx := utils.NewCancelableExecutionCtx()
140-
client := &OptimizelyClient{
141-
executionCtx: executionCtx,
142-
}
143-
144136
notificationCenter := notification.NewNotificationCenter()
145137

146-
switch {
147-
case clientOptions.ProjectConfigManager != nil:
148-
client.configManager = clientOptions.ProjectConfigManager
149-
case f.SDKKey != "":
150-
options := config.PollingProjectConfigManagerOptions{
151-
Datafile: f.Datafile,
152-
}
153-
client.configManager = config.NewPollingProjectConfigManagerWithOptions(executionCtx, f.SDKKey, options)
154-
case f.Datafile != nil:
155-
staticConfigManager, _ := config.NewStaticProjectConfigManagerFromPayload(f.Datafile)
156-
client.configManager = staticConfigManager
157-
default:
158-
return client, errors.New("unable to instantiate client: no project config manager, SDK key, or a Datafile provided")
159-
}
160-
161-
if clientOptions.DecisionService != nil {
162-
client.decisionService = clientOptions.DecisionService
163-
} else {
164-
client.decisionService = decision.NewCompositeService(notificationCenter)
165-
}
166-
167-
if clientOptions.EventProcessor != nil {
168-
client.eventProcessor = clientOptions.EventProcessor
169-
} else {
170-
client.eventProcessor = event.NewEventProcessor(executionCtx, event.DefaultBatchSize, event.DefaultEventQueueSize, event.DefaultEventFlushInterval)
171-
}
172-
173-
return client, nil
174-
}
175-
176-
// Client returns a client initialized with the defaults
177-
func (f OptimizelyFactory) Client() (*OptimizelyClient, error) {
178-
// Creates a default, canceleable context
179-
clientOptions := Options{}
180-
client, err := f.ClientWithOptions(clientOptions)
181-
return client, err
138+
optlyClient, e := f.Client(
139+
ConfigManager(configManager),
140+
CompositeDecisionService(notificationCenter),
141+
BatchEventProcessor(event.DefaultBatchSize, event.DefaultEventQueueSize, event.DefaultEventFlushInterval),
142+
)
143+
return optlyClient, e
182144
}

optimizely/client/factory_test.go

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"github.com/optimizely/go-sdk/optimizely/config"
2424
"github.com/optimizely/go-sdk/optimizely/config/datafileprojectconfig"
2525
"github.com/optimizely/go-sdk/optimizely/event"
26+
2627
"github.com/stretchr/testify/assert"
2728
)
2829

@@ -48,41 +49,23 @@ func TestFactoryClientReturnsDefaultClient(t *testing.T) {
4849
func TestClientWithSDKKey(t *testing.T) {
4950
factory := OptimizelyFactory{SDKKey: "1212"}
5051

51-
clientOptions := Options{}
52-
53-
client, err := factory.ClientWithOptions(clientOptions)
52+
optimizelyClient, err := factory.Client()
5453
assert.NoError(t, err)
55-
assert.NotNil(t, client.configManager)
56-
assert.NotNil(t, client.decisionService)
57-
assert.NotNil(t, client.eventProcessor)
54+
assert.NotNil(t, optimizelyClient.configManager)
55+
assert.NotNil(t, optimizelyClient.decisionService)
56+
assert.NotNil(t, optimizelyClient.eventProcessor)
5857
}
5958

6059
func TestClientWithProjectConfigManagerInOptions(t *testing.T) {
6160
factory := OptimizelyFactory{}
6261
projectConfig := datafileprojectconfig.DatafileProjectConfig{}
6362
configManager := config.NewStaticProjectConfigManager(projectConfig)
6463

65-
clientOptions := Options{ProjectConfigManager: configManager}
66-
67-
client, err := factory.ClientWithOptions(clientOptions)
68-
assert.NoError(t, err)
69-
assert.NotNil(t, client.configManager)
70-
assert.NotNil(t, client.decisionService)
71-
assert.NotNil(t, client.eventProcessor)
72-
}
73-
74-
func TestClientWithNoDecisionServiceAndEventProcessorInOptions(t *testing.T) {
75-
factory := OptimizelyFactory{}
76-
projectConfig := datafileprojectconfig.DatafileProjectConfig{}
77-
configManager := config.NewStaticProjectConfigManager(projectConfig)
78-
79-
clientOptions := Options{ProjectConfigManager: configManager}
80-
81-
client, err := factory.ClientWithOptions(clientOptions)
64+
optimizelyClient, err := factory.Client(ConfigManager(configManager))
8265
assert.NoError(t, err)
83-
assert.NotNil(t, client.configManager)
84-
assert.NotNil(t, client.decisionService)
85-
assert.NotNil(t, client.eventProcessor)
66+
assert.NotNil(t, optimizelyClient.configManager)
67+
assert.NotNil(t, optimizelyClient.decisionService)
68+
assert.NotNil(t, optimizelyClient.eventProcessor)
8669
}
8770

8871
func TestClientWithDecisionServiceAndEventProcessorInOptions(t *testing.T) {
@@ -97,26 +80,8 @@ func TestClientWithDecisionServiceAndEventProcessorInOptions(t *testing.T) {
9780
EventDispatcher: &MockDispatcher{},
9881
}
9982

100-
clientOptions := Options{
101-
ProjectConfigManager: configManager,
102-
DecisionService: decisionService,
103-
EventProcessor: processor,
104-
}
105-
106-
client, err := factory.ClientWithOptions(clientOptions)
83+
optimizelyClient, err := factory.Client(ConfigManager(configManager), DecisionService(decisionService), EventProcessor(processor))
10784
assert.NoError(t, err)
108-
assert.Equal(t, decisionService, client.decisionService)
109-
assert.Equal(t, processor, client.eventProcessor)
110-
}
111-
112-
func TestClientWithOptionsErrorCase(t *testing.T) {
113-
// Error when no config manager, sdk key, or datafile is provided
114-
factory := OptimizelyFactory{}
115-
clientOptions := Options{}
116-
117-
_, err := factory.ClientWithOptions(clientOptions)
118-
expectedErr := errors.New("unable to instantiate client: no project config manager, SDK key, or a Datafile provided")
119-
if assert.Error(t, err) {
120-
assert.Equal(t, err, expectedErr)
121-
}
85+
assert.Equal(t, decisionService, optimizelyClient.decisionService)
86+
assert.Equal(t, processor, optimizelyClient.eventProcessor)
12287
}

0 commit comments

Comments
 (0)