@@ -67,6 +67,16 @@ func NewWithStorageAndCallback(cache Cache, storage storage.Storage, callback Ca
67
67
}
68
68
}
69
69
70
+ func (r FFRepository ) getFlags (envID string ) ([]rest.FeatureConfig , error ) {
71
+ flagsKey := formatFlagsKey (envID )
72
+ flags , ok := r .cache .Get (flagsKey )
73
+ if ok {
74
+ return flags .([]rest.FeatureConfig ), nil
75
+ }
76
+
77
+ return []rest.FeatureConfig {}, fmt .Errorf ("%w with environment: %s" , ErrFeatureConfigNotFound , envID )
78
+ }
79
+
70
80
func (r FFRepository ) getFlagAndCache (identifier string , cacheable bool ) (rest.FeatureConfig , error ) {
71
81
flagKey := formatFlagKey (identifier )
72
82
flag , ok := r .cache .Get (flagKey )
@@ -119,7 +129,8 @@ func (r FFRepository) GetSegment(identifier string) (rest.Segment, error) {
119
129
// SetFlag places a flag in the repository with the new value
120
130
func (r FFRepository ) SetFlag (featureConfig rest.FeatureConfig , initialLoad bool ) {
121
131
if ! initialLoad {
122
- if r .isFlagOutdated (featureConfig ) {
132
+ // If the flag is up to date then we don't need to bother updating the cache
133
+ if ! r .isFlagOutdated (featureConfig ) {
123
134
return
124
135
}
125
136
}
@@ -141,7 +152,8 @@ func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig, initialLoad bool
141
152
// SetFlags places all the flags in the repository
142
153
func (r FFRepository ) SetFlags (initialLoad bool , envID string , featureConfigs ... rest.FeatureConfig ) {
143
154
if ! initialLoad {
144
- if r .areFlagsOutdated (featureConfigs ... ) {
155
+ // If the flags are all up to date then we don't need to bother updating the cache and can exit
156
+ if ! r .areFlagsOutdated (envID , featureConfigs ... ) {
145
157
return
146
158
}
147
159
}
@@ -165,7 +177,8 @@ func (r FFRepository) SetFlags(initialLoad bool, envID string, featureConfigs ..
165
177
// SetSegment places a segment in the repository with the new value
166
178
func (r FFRepository ) SetSegment (segment rest.Segment , initialLoad bool ) {
167
179
if ! initialLoad {
168
- if r .isSegmentOutdated (segment ) {
180
+ // If the segment isn't outdated then we can exit as we don't need to refresh the cache
181
+ if ! r .isSegmentOutdated (segment ) {
169
182
return
170
183
}
171
184
}
@@ -187,7 +200,8 @@ func (r FFRepository) SetSegment(segment rest.Segment, initialLoad bool) {
187
200
// SetSegments places all the segments in the repository
188
201
func (r FFRepository ) SetSegments (initialLoad bool , envID string , segments ... rest.Segment ) {
189
202
if ! initialLoad {
190
- if r .areSegmentsOutdated (segments ... ) {
203
+ // If segments aren't outdated then we can exit as we don't need to refresh the cache
204
+ if ! r .areSegmentsOutdated (segments ... ) {
191
205
return
192
206
}
193
207
}
@@ -204,7 +218,7 @@ func (r FFRepository) SetSegments(initialLoad bool, envID string, segments ...re
204
218
}
205
219
206
220
if r .callback != nil {
207
- r .callback .OnFlagsStored (envID )
221
+ r .callback .OnSegmentsStored (envID )
208
222
}
209
223
}
210
224
@@ -243,15 +257,52 @@ func (r FFRepository) DeleteSegment(identifier string) {
243
257
func (r FFRepository ) isFlagOutdated (featureConfig rest.FeatureConfig ) bool {
244
258
oldFlag , err := r .getFlagAndCache (featureConfig .Feature , false )
245
259
if err != nil || oldFlag .Version == nil {
246
- return false
260
+ // If we get an error here return true to force a cache update
261
+ return true
247
262
}
248
263
249
- return * oldFlag .Version >= * featureConfig .Version
264
+ return * oldFlag .Version < * featureConfig .Version
250
265
}
251
266
252
- func (r FFRepository ) areFlagsOutdated (flags ... rest.FeatureConfig ) bool {
267
+ func (r FFRepository ) getFlagsAndCache (envID string , cacheable bool ) ([]rest.FeatureConfig , error ) {
268
+ flagKey := formatFlagsKey (envID )
269
+ flag , ok := r .cache .Get (flagKey )
270
+ if ok {
271
+ return flag .([]rest.FeatureConfig ), nil
272
+ }
273
+
274
+ if r .storage != nil {
275
+ flag , ok := r .storage .Get (flagKey )
276
+ if ok && cacheable {
277
+ r .cache .Set (flagKey , flag )
278
+ return flag .([]rest.FeatureConfig ), nil
279
+ }
280
+ }
281
+ return []rest.FeatureConfig {}, fmt .Errorf ("%w with identifier: %s" , ErrFeatureConfigNotFound , envID )
282
+ }
283
+
284
+ func (r FFRepository ) areFlagsOutdated (envID string , flags ... rest.FeatureConfig ) bool {
285
+
286
+ oldFlags , err := r .getFlags (envID )
287
+ if err != nil {
288
+ // If we get an error return true to force a cache refresh
289
+ return true
290
+ }
291
+
292
+ oldFlagMap := map [string ]rest.FeatureConfig {}
293
+ for _ , v := range oldFlags {
294
+ oldFlagMap [v .Feature ] = v
295
+ }
296
+
253
297
for _ , flag := range flags {
254
- if r .isFlagOutdated (flag ) {
298
+ of , ok := oldFlagMap [flag .Feature ]
299
+ if ! ok {
300
+ // If a new flag isn't in the oldFlagMap then the list of old flags are outdated and we'll
301
+ // want to refresh the cache
302
+ return true
303
+ }
304
+
305
+ if * of .Version < * flag .Version {
255
306
return true
256
307
}
257
308
}
@@ -261,10 +312,11 @@ func (r FFRepository) areFlagsOutdated(flags ...rest.FeatureConfig) bool {
261
312
func (r FFRepository ) isSegmentOutdated (segment rest.Segment ) bool {
262
313
oldSegment , err := r .getSegmentAndCache (segment .Identifier , false )
263
314
if err != nil || oldSegment .Version == nil {
264
- return false
315
+ // If we get an error here return true to force a cache update
316
+ return true
265
317
}
266
318
267
- return * oldSegment .Version >= * segment .Version
319
+ return * oldSegment .Version < * segment .Version
268
320
}
269
321
270
322
func (r FFRepository ) areSegmentsOutdated (segments ... rest.Segment ) bool {
0 commit comments