Skip to content

Commit 3799500

Browse files
committed
FFM-9314 Check all flags to see if a single one is outdated
**What** - Changes conditon so we only break out of SetFlags if the flags ARE NOT outdated **Why** - If the flags are outdated we want to carry on inside SetFlags and refresh the cache
1 parent c029419 commit 3799500

File tree

2 files changed

+393
-26
lines changed

2 files changed

+393
-26
lines changed

pkg/repository/repository.go

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ func NewWithStorageAndCallback(cache Cache, storage storage.Storage, callback Ca
6767
}
6868
}
6969

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+
7080
func (r FFRepository) getFlagAndCache(identifier string, cacheable bool) (rest.FeatureConfig, error) {
7181
flagKey := formatFlagKey(identifier)
7282
flag, ok := r.cache.Get(flagKey)
@@ -119,7 +129,8 @@ func (r FFRepository) GetSegment(identifier string) (rest.Segment, error) {
119129
// SetFlag places a flag in the repository with the new value
120130
func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig, initialLoad bool) {
121131
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) {
123134
return
124135
}
125136
}
@@ -141,7 +152,8 @@ func (r FFRepository) SetFlag(featureConfig rest.FeatureConfig, initialLoad bool
141152
// SetFlags places all the flags in the repository
142153
func (r FFRepository) SetFlags(initialLoad bool, envID string, featureConfigs ...rest.FeatureConfig) {
143154
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...) {
145157
return
146158
}
147159
}
@@ -165,7 +177,8 @@ func (r FFRepository) SetFlags(initialLoad bool, envID string, featureConfigs ..
165177
// SetSegment places a segment in the repository with the new value
166178
func (r FFRepository) SetSegment(segment rest.Segment, initialLoad bool) {
167179
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) {
169182
return
170183
}
171184
}
@@ -187,7 +200,8 @@ func (r FFRepository) SetSegment(segment rest.Segment, initialLoad bool) {
187200
// SetSegments places all the segments in the repository
188201
func (r FFRepository) SetSegments(initialLoad bool, envID string, segments ...rest.Segment) {
189202
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...) {
191205
return
192206
}
193207
}
@@ -204,7 +218,7 @@ func (r FFRepository) SetSegments(initialLoad bool, envID string, segments ...re
204218
}
205219

206220
if r.callback != nil {
207-
r.callback.OnFlagsStored(envID)
221+
r.callback.OnSegmentsStored(envID)
208222
}
209223
}
210224

@@ -243,15 +257,52 @@ func (r FFRepository) DeleteSegment(identifier string) {
243257
func (r FFRepository) isFlagOutdated(featureConfig rest.FeatureConfig) bool {
244258
oldFlag, err := r.getFlagAndCache(featureConfig.Feature, false)
245259
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
247262
}
248263

249-
return *oldFlag.Version >= *featureConfig.Version
264+
return *oldFlag.Version < *featureConfig.Version
250265
}
251266

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+
253297
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 {
255306
return true
256307
}
257308
}
@@ -261,10 +312,11 @@ func (r FFRepository) areFlagsOutdated(flags ...rest.FeatureConfig) bool {
261312
func (r FFRepository) isSegmentOutdated(segment rest.Segment) bool {
262313
oldSegment, err := r.getSegmentAndCache(segment.Identifier, false)
263314
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
265317
}
266318

267-
return *oldSegment.Version >= *segment.Version
319+
return *oldSegment.Version < *segment.Version
268320
}
269321

270322
func (r FFRepository) areSegmentsOutdated(segments ...rest.Segment) bool {

0 commit comments

Comments
 (0)