@@ -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+
7080func (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
120130func (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
142153func (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
166178func (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
188201func (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) {
243257func (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 {
261312func (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
270322func (r FFRepository ) areSegmentsOutdated (segments ... rest.Segment ) bool {
0 commit comments