@@ -95,52 +95,47 @@ func WithInitialDatafile(datafile []byte) OptionFunc {
95
95
}
96
96
}
97
97
98
- // SyncConfig gets current datafile and updates projectConfig
99
- func (cm * PollingProjectConfigManager ) SyncConfig (datafile [] byte ) {
98
+ // SyncConfig downloads datafile and updates projectConfig
99
+ func (cm * PollingProjectConfigManager ) SyncConfig () {
100
100
var e error
101
101
var code int
102
102
var respHeaders http.Header
103
+ var datafile []byte
103
104
104
105
closeMutex := func (e error ) {
105
106
cm .err = e
106
107
cm .configLock .Unlock ()
107
108
}
108
109
109
110
url := fmt .Sprintf (cm .datafileURLTemplate , cm .sdkKey )
110
- if len (datafile ) == 0 {
111
- if cm .lastModified != "" {
112
- lastModifiedHeader := utils.Header {Name : ModifiedSince , Value : cm .lastModified }
113
- datafile , respHeaders , code , e = cm .requester .Get (url , lastModifiedHeader )
114
- } else {
115
- datafile , respHeaders , code , e = cm .requester .Get (url )
116
- }
117
-
118
- if e != nil {
119
- msg := "unable to fetch fresh datafile"
120
- cmLogger .Warning (msg )
121
- cm .configLock .Lock ()
122
- closeMutex (errors .New (fmt .Sprintf ("%s, reason (http status code): %s" , msg , e .Error ())))
123
- return
124
- }
125
-
126
- if code == http .StatusNotModified {
127
- cmLogger .Debug ("The datafile was not modified and won't be downloaded again" )
128
- return
129
- }
111
+ if cm .lastModified != "" {
112
+ lastModifiedHeader := utils.Header {Name : ModifiedSince , Value : cm .lastModified }
113
+ datafile , respHeaders , code , e = cm .requester .Get (url , lastModifiedHeader )
114
+ } else {
115
+ datafile , respHeaders , code , e = cm .requester .Get (url )
116
+ }
130
117
131
- // Save last-modified date from response header
132
- lastModified := respHeaders .Get (LastModified )
133
- if lastModified != "" {
134
- cm .configLock .Lock ()
135
- cm .lastModified = lastModified
136
- cm .configLock .Unlock ()
137
- }
118
+ if e != nil {
119
+ msg := "unable to fetch fresh datafile"
120
+ cmLogger .Warning (msg )
121
+ cm .configLock .Lock ()
122
+ closeMutex (errors .New (fmt .Sprintf ("%s, reason (http status code): %s" , msg , e .Error ())))
123
+ return
138
124
}
139
125
140
- projectConfig , err := datafileprojectconfig .NewDatafileProjectConfig (datafile )
126
+ if code == http .StatusNotModified {
127
+ cmLogger .Debug ("The datafile was not modified and won't be downloaded again" )
128
+ return
129
+ }
141
130
131
+ // Save last-modified date from response header
142
132
cm .configLock .Lock ()
133
+ lastModified := respHeaders .Get (LastModified )
134
+ if lastModified != "" {
135
+ cm .lastModified = lastModified
136
+ }
143
137
138
+ projectConfig , err := datafileprojectconfig .NewDatafileProjectConfig (datafile )
144
139
if err != nil {
145
140
cmLogger .Warning ("failed to create project config" )
146
141
closeMutex (errors .New ("unable to parse datafile" ))
@@ -156,21 +151,11 @@ func (cm *PollingProjectConfigManager) SyncConfig(datafile []byte) {
156
151
closeMutex (nil )
157
152
return
158
153
}
159
- cmLogger .Debug (fmt .Sprintf ("New datafile set with revision: %s. Old revision: %s" , projectConfig .GetRevision (), previousRevision ))
160
- cm .projectConfig = projectConfig
161
- if cm .optimizelyConfig != nil {
162
- cm .optimizelyConfig = NewOptimizelyConfig (projectConfig )
163
- }
164
- closeMutex (nil )
165
-
166
- if cm .notificationCenter != nil {
167
- projectConfigUpdateNotification := notification.ProjectConfigUpdateNotification {
168
- Type : notification .ProjectConfigUpdate ,
169
- Revision : cm .projectConfig .GetRevision (),
170
- }
171
- if err = cm .notificationCenter .Send (notification .ProjectConfigUpdate , projectConfigUpdateNotification ); err != nil {
172
- cmLogger .Warning ("Problem with sending notification" )
173
- }
154
+ err = cm .setConfig (projectConfig )
155
+ closeMutex (err )
156
+ if err == nil {
157
+ cmLogger .Debug (fmt .Sprintf ("New datafile set with revision: %s. Old revision: %s" , projectConfig .GetRevision (), previousRevision ))
158
+ cm .sendConfigUpdateNotification ()
174
159
}
175
160
}
176
161
@@ -181,7 +166,7 @@ func (cm *PollingProjectConfigManager) Start(ctx context.Context) {
181
166
for {
182
167
select {
183
168
case <- t .C :
184
- cm .SyncConfig ([] byte {} )
169
+ cm .SyncConfig ()
185
170
case <- ctx .Done ():
186
171
cmLogger .Debug ("Polling Config Manager Stopped" )
187
172
return
@@ -204,8 +189,30 @@ func NewPollingProjectConfigManager(sdkKey string, pollingMangerOptions ...Optio
204
189
opt (& pollingProjectConfigManager )
205
190
}
206
191
207
- initDatafile := pollingProjectConfigManager .initDatafile
208
- pollingProjectConfigManager .SyncConfig (initDatafile ) // initial poll
192
+ if len (pollingProjectConfigManager .initDatafile ) > 0 {
193
+ pollingProjectConfigManager .setInitialDatafile (pollingProjectConfigManager .initDatafile )
194
+ } else {
195
+ pollingProjectConfigManager .SyncConfig () // initial poll
196
+ }
197
+ return & pollingProjectConfigManager
198
+ }
199
+
200
+ // NewAsyncPollingProjectConfigManager returns an instance of the async polling config manager with the customized configuration
201
+ func NewAsyncPollingProjectConfigManager (sdkKey string , pollingMangerOptions ... OptionFunc ) * PollingProjectConfigManager {
202
+
203
+ pollingProjectConfigManager := PollingProjectConfigManager {
204
+ notificationCenter : registry .GetNotificationCenter (sdkKey ),
205
+ pollingInterval : DefaultPollingInterval ,
206
+ requester : utils .NewHTTPRequester (),
207
+ datafileURLTemplate : DatafileURLTemplate ,
208
+ sdkKey : sdkKey ,
209
+ }
210
+
211
+ for _ , opt := range pollingMangerOptions {
212
+ opt (& pollingProjectConfigManager )
213
+ }
214
+
215
+ pollingProjectConfigManager .setInitialDatafile (pollingProjectConfigManager .initDatafile )
209
216
return & pollingProjectConfigManager
210
217
}
211
218
@@ -256,3 +263,38 @@ func (cm *PollingProjectConfigManager) RemoveOnProjectConfigUpdate(id int) error
256
263
}
257
264
return nil
258
265
}
266
+
267
+ func (cm * PollingProjectConfigManager ) setConfig (projectConfig ProjectConfig ) error {
268
+ if projectConfig == nil {
269
+ return errors .New ("unable to set nil config" )
270
+ }
271
+ cm .projectConfig = projectConfig
272
+ if cm .optimizelyConfig != nil {
273
+ cm .optimizelyConfig = NewOptimizelyConfig (projectConfig )
274
+ }
275
+ return nil
276
+ }
277
+
278
+ func (cm * PollingProjectConfigManager ) setInitialDatafile (datafile []byte ) {
279
+ if len (datafile ) != 0 {
280
+ cm .configLock .Lock ()
281
+ defer cm .configLock .Unlock ()
282
+ projectConfig , err := datafileprojectconfig .NewDatafileProjectConfig (datafile )
283
+ if projectConfig != nil {
284
+ err = cm .setConfig (projectConfig )
285
+ }
286
+ cm .err = err
287
+ }
288
+ }
289
+
290
+ func (cm * PollingProjectConfigManager ) sendConfigUpdateNotification () {
291
+ if cm .notificationCenter != nil {
292
+ projectConfigUpdateNotification := notification.ProjectConfigUpdateNotification {
293
+ Type : notification .ProjectConfigUpdate ,
294
+ Revision : cm .projectConfig .GetRevision (),
295
+ }
296
+ if err := cm .notificationCenter .Send (notification .ProjectConfigUpdate , projectConfigUpdateNotification ); err != nil {
297
+ cmLogger .Warning ("Problem with sending notification" )
298
+ }
299
+ }
300
+ }
0 commit comments