@@ -29,31 +29,67 @@ import (
2929 "github.com/optimizely/go-sdk/optimizely/utils"
3030)
3131
32- const defaultPollingInterval = 5 * time .Minute // default to 5 minutes for polling
32+ // DefaultPollingInterval sets default interval for polling manager
33+ const DefaultPollingInterval = 5 * time .Minute // default to 5 minutes for polling
3334
3435// DatafileURLTemplate is used to construct the endpoint for retrieving the datafile from the CDN
3536const DatafileURLTemplate = "https://cdn.optimizely.com/datafiles/%s.json"
3637
3738var cmLogger = logging .GetLogger ("PollingConfigManager" )
3839
39- // PollingProjectConfigManagerOptions used to create an instance with custom configuration
40- type PollingProjectConfigManagerOptions struct {
41- Datafile []byte
42- PollingInterval time.Duration
43- Requester utils.Requester
44- NotificationCenter notification.Center
45- }
46-
4740// PollingProjectConfigManager maintains a dynamic copy of the project config
4841type PollingProjectConfigManager struct {
4942 requester utils.Requester
5043 pollingInterval time.Duration
51- projectConfig optimizely.ProjectConfig
52- configLock sync.RWMutex
53- err error
5444 notificationCenter notification.Center
45+ initDatafile []byte
46+
47+ configLock sync.RWMutex
48+ err error
49+ projectConfig optimizely.ProjectConfig
50+ exeCtx utils.ExecutionCtx // context used for execution control
51+ }
52+
53+ // OptionFunc is a type to a proper func
54+ type OptionFunc func (* PollingProjectConfigManager )
55+
56+ // SetDefaultRequester is an optional function, sets default requester based on a key.
57+ func SetDefaultRequester (sdkKey string ) OptionFunc {
58+ return func (p * PollingProjectConfigManager ) {
59+
60+ url := fmt .Sprintf (DatafileURLTemplate , sdkKey )
61+ requester := utils .NewHTTPRequester (url )
5562
56- exeCtx utils.ExecutionCtx // context used for execution control
63+ p .requester = requester
64+ }
65+ }
66+
67+ // SetRequester is an optional function, sets a passed requester
68+ func SetRequester (requester utils.Requester ) OptionFunc {
69+ return func (p * PollingProjectConfigManager ) {
70+ p .requester = requester
71+ }
72+ }
73+
74+ // SetPollingInterval is an optional function, sets a passed polling interval
75+ func SetPollingInterval (interval time.Duration ) OptionFunc {
76+ return func (p * PollingProjectConfigManager ) {
77+ p .pollingInterval = interval
78+ }
79+ }
80+
81+ // SetNotification is an optional function, sets a passed notification
82+ func SetNotification (notificationCenter notification.Center ) OptionFunc {
83+ return func (p * PollingProjectConfigManager ) {
84+ p .notificationCenter = notificationCenter
85+ }
86+ }
87+
88+ // SetInitialDatafile is an optional function, sets a passed datafile
89+ func SetInitialDatafile (datafile []byte ) OptionFunc {
90+ return func (p * PollingProjectConfigManager ) {
91+ p .initDatafile = datafile
92+ }
5793}
5894
5995// SyncConfig gets current datafile and updates projectConfig
@@ -98,12 +134,7 @@ func (cm *PollingProjectConfigManager) SyncConfig(datafile []byte) {
98134 cm .configLock .Unlock ()
99135}
100136
101- func (cm * PollingProjectConfigManager ) start (initialDatafile []byte , init bool ) {
102-
103- if init {
104- cm .SyncConfig (initialDatafile )
105- return
106- }
137+ func (cm * PollingProjectConfigManager ) start () {
107138
108139 t := time .NewTicker (cm .pollingInterval )
109140 for {
@@ -117,38 +148,24 @@ func (cm *PollingProjectConfigManager) start(initialDatafile []byte, init bool)
117148 }
118149}
119150
120- // NewPollingProjectConfigManagerWithOptions returns new instance of PollingProjectConfigManager with the given options
121- func NewPollingProjectConfigManagerWithOptions (exeCtx utils.ExecutionCtx , sdkKey string , options PollingProjectConfigManagerOptions ) * PollingProjectConfigManager {
151+ // NewPollingProjectConfigManager returns an instance of the polling config manager with the customized configuration
152+ func NewPollingProjectConfigManager (exeCtx utils.ExecutionCtx , sdkKey string , pollingMangerOptions ... OptionFunc ) * PollingProjectConfigManager {
153+ url := fmt .Sprintf (DatafileURLTemplate , sdkKey )
122154
123- var requester utils.Requester
124- if options .Requester != nil {
125- requester = options .Requester
126- } else {
127- url := fmt .Sprintf (DatafileURLTemplate , sdkKey )
128- requester = utils .NewHTTPRequester (url )
129- }
155+ pollingProjectConfigManager := PollingProjectConfigManager {exeCtx : exeCtx , pollingInterval : DefaultPollingInterval , requester : utils .NewHTTPRequester (url )}
130156
131- pollingInterval := options .PollingInterval
132- if pollingInterval == 0 {
133- pollingInterval = defaultPollingInterval
157+ for _ , opt := range pollingMangerOptions {
158+ opt (& pollingProjectConfigManager )
134159 }
135160
136- pollingProjectConfigManager := PollingProjectConfigManager {requester : requester , pollingInterval : pollingInterval , notificationCenter : options .NotificationCenter , exeCtx : exeCtx }
137-
138- pollingProjectConfigManager .SyncConfig (options .Datafile ) // initial poll
161+ initDatafile := pollingProjectConfigManager .initDatafile
162+ pollingProjectConfigManager .SyncConfig (initDatafile ) // initial poll
139163
140164 cmLogger .Debug ("Polling Config Manager Initiated" )
141- go pollingProjectConfigManager .start ([] byte {}, false )
165+ go pollingProjectConfigManager .start ()
142166 return & pollingProjectConfigManager
143167}
144168
145- // NewPollingProjectConfigManager returns an instance of the polling config manager with the default configuration
146- func NewPollingProjectConfigManager (exeCtx utils.ExecutionCtx , sdkKey string ) * PollingProjectConfigManager {
147- options := PollingProjectConfigManagerOptions {}
148- configManager := NewPollingProjectConfigManagerWithOptions (exeCtx , sdkKey , options )
149- return configManager
150- }
151-
152169// GetConfig returns the project config
153170func (cm * PollingProjectConfigManager ) GetConfig () (optimizely.ProjectConfig , error ) {
154171 cm .configLock .RLock ()
0 commit comments