Skip to content

Commit 4ea84b7

Browse files
authored
Merge pull request #324 from splitio/task/rbStorageproxy
added rbsproxystorage
2 parents 7f46c3d + 994902e commit 4ea84b7

15 files changed

Lines changed: 285 additions & 77 deletions

File tree

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ require (
88
github.com/gin-gonic/gin v1.10.1
99
github.com/google/uuid v1.3.0
1010
github.com/splitio/gincache v1.0.1
11-
github.com/splitio/go-split-commons/v8 v8.0.0-20251022154508-1ea26a26874f
11+
github.com/splitio/go-split-commons/v8 v8.0.0-20251028203151-2b6d18a2f657
1212
github.com/splitio/go-toolkit/v5 v5.4.1
1313
github.com/stretchr/testify v1.11.1
1414
go.etcd.io/bbolt v1.3.6

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
7474
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
7575
github.com/splitio/gincache v1.0.1 h1:dLYdANY/BqH4KcUMCe/LluLyV5WtuE/LEdQWRE06IXU=
7676
github.com/splitio/gincache v1.0.1/go.mod h1:CcgJDSM9Af75kyBH0724v55URVwMBuSj5x1eCWIOECY=
77-
github.com/splitio/go-split-commons/v8 v8.0.0-20251022154508-1ea26a26874f h1:2o8Hu3G4jAoF6Y0Ceptr4Bwp3x9wFDenp494Cu/V5nU=
78-
github.com/splitio/go-split-commons/v8 v8.0.0-20251022154508-1ea26a26874f/go.mod h1:vgRGPn0s4RC9/zp1nIn4KeeIEj/K3iXE2fxYQbCk/WI=
77+
github.com/splitio/go-split-commons/v8 v8.0.0-20251028203151-2b6d18a2f657 h1:FYT0P+uFnXzALLgWOTIAJS6P4J1NpMGNi+rWsv2ZIkU=
78+
github.com/splitio/go-split-commons/v8 v8.0.0-20251028203151-2b6d18a2f657/go.mod h1:vgRGPn0s4RC9/zp1nIn4KeeIEj/K3iXE2fxYQbCk/WI=
7979
github.com/splitio/go-toolkit/v5 v5.4.1 h1:srTyvDBJZMUcJ/KiiQDMyjCuELVgTBh2TGRVn0sOXEE=
8080
github.com/splitio/go-toolkit/v5 v5.4.1/go.mod h1:SifzysrOVDbzMcOE8zjX02+FG5az4FrR3Us/i5SeStw=
8181
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

splitio/admin/common/config.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
package common
22

3-
import "github.com/splitio/go-split-commons/v8/storage"
3+
import (
4+
"github.com/splitio/go-split-commons/v8/engine/grammar/constants"
5+
"github.com/splitio/go-split-commons/v8/storage"
6+
)
7+
8+
var ProducerFeatureFlagsRules = []string{constants.MatcherTypeAllKeys, constants.MatcherTypeInSegment, constants.MatcherTypeWhitelist, constants.MatcherTypeEqualTo, constants.MatcherTypeGreaterThanOrEqualTo, constants.MatcherTypeLessThanOrEqualTo, constants.MatcherTypeBetween,
9+
constants.MatcherTypeEqualToSet, constants.MatcherTypePartOfSet, constants.MatcherTypeContainsAllOfSet, constants.MatcherTypeContainsAnyOfSet, constants.MatcherTypeStartsWith, constants.MatcherTypeEndsWith, constants.MatcherTypeContainsString, constants.MatcherTypeInSplitTreatment,
10+
constants.MatcherTypeEqualToBoolean, constants.MatcherTypeMatchesString, constants.MatcherEqualToSemver, constants.MatcherTypeGreaterThanOrEqualToSemver, constants.MatcherTypeLessThanOrEqualToSemver, constants.MatcherTypeBetweenSemver, constants.MatcherTypeInListSemver,
11+
constants.MatcherTypeInRuleBasedSegment}
12+
13+
var ProducerRuleBasedSegmentRules = []string{constants.MatcherTypeAllKeys, constants.MatcherTypeInSegment, constants.MatcherTypeWhitelist, constants.MatcherTypeEqualTo, constants.MatcherTypeGreaterThanOrEqualTo, constants.MatcherTypeLessThanOrEqualTo, constants.MatcherTypeBetween,
14+
constants.MatcherTypeEqualToSet, constants.MatcherTypePartOfSet, constants.MatcherTypeContainsAllOfSet, constants.MatcherTypeContainsAnyOfSet, constants.MatcherTypeStartsWith, constants.MatcherTypeEndsWith, constants.MatcherTypeContainsString,
15+
constants.MatcherTypeEqualToBoolean, constants.MatcherTypeMatchesString, constants.MatcherEqualToSemver, constants.MatcherTypeGreaterThanOrEqualToSemver, constants.MatcherTypeLessThanOrEqualToSemver, constants.MatcherTypeBetweenSemver, constants.MatcherTypeInListSemver,
16+
constants.MatcherTypeInRuleBasedSegment}
417

518
// Storages wraps storages in one struct
619
type Storages struct {
7-
SplitStorage storage.SplitStorage
8-
SegmentStorage storage.SegmentStorage
9-
LocalTelemetryStorage storage.TelemetryRuntimeConsumer
10-
EventStorage storage.EventMultiSdkConsumer
11-
ImpressionStorage storage.ImpressionMultiSdkConsumer
12-
UniqueKeysStorage storage.UniqueKeysMultiSdkConsumer
13-
LargeSegmentStorage storage.LargeSegmentsStorage
20+
SplitStorage storage.SplitStorage
21+
SegmentStorage storage.SegmentStorage
22+
LocalTelemetryStorage storage.TelemetryRuntimeConsumer
23+
EventStorage storage.EventMultiSdkConsumer
24+
ImpressionStorage storage.ImpressionMultiSdkConsumer
25+
UniqueKeysStorage storage.UniqueKeysMultiSdkConsumer
26+
LargeSegmentStorage storage.LargeSegmentsStorage
27+
RuleBasedSegmentsStorage storage.RuleBasedSegmentsStorage
1428
}

splitio/commitversion.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@ This file is created automatically, please do not edit
55
*/
66

77
// CommitVersion is the version of the last commit previous to release
8-
const CommitVersion = "5e4d9e1"
8+
const CommitVersion = "1807589"

splitio/producer/conf/sections.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ type Main struct {
1818
Integrations conf.Integrations `json:"integrations" s-nested:"true"`
1919
Logging conf.Logging `json:"logging" s-nested:"true"`
2020
Healthcheck Healthcheck `json:"healthcheck" s-nested:"true"`
21-
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.1" s-desc:"Spec version for flags"`
21+
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.3" s-desc:"Spec version for flags"`
2222
}
2323

2424
// BuildAdvancedConfig generates a commons-compatible advancedconfig with default + overriden parameters

splitio/producer/initialization.go

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,13 @@ func Start(logger logging.LoggerInterface, cfg *conf.Main) error {
103103
return fmt.Errorf("error instantiating observable segment storage: %w", err)
104104
}
105105
storages := adminCommon.Storages{
106-
SplitStorage: splitStorage,
107-
SegmentStorage: segmentStorage,
108-
LocalTelemetryStorage: syncTelemetryStorage,
109-
ImpressionStorage: redis.NewImpressionStorage(redisClient, dtos.Metadata{}, logger),
110-
EventStorage: redis.NewEventsStorage(redisClient, dtos.Metadata{}, logger),
111-
UniqueKeysStorage: redis.NewUniqueKeysMultiSdkConsumer(redisClient, logger),
106+
SplitStorage: splitStorage,
107+
SegmentStorage: segmentStorage,
108+
LocalTelemetryStorage: syncTelemetryStorage,
109+
ImpressionStorage: redis.NewImpressionStorage(redisClient, dtos.Metadata{}, logger),
110+
EventStorage: redis.NewEventsStorage(redisClient, dtos.Metadata{}, logger),
111+
UniqueKeysStorage: redis.NewUniqueKeysMultiSdkConsumer(redisClient, logger),
112+
RuleBasedSegmentsStorage: redis.NewRuleBasedStorage(redisClient, logger),
112113
}
113114

114115
// Healcheck Monitor
@@ -125,11 +126,19 @@ func Start(logger logging.LoggerInterface, cfg *conf.Main) error {
125126
// Creating Workers and Tasks
126127
eventEvictionMonitor := evcalc.New(1)
127128

129+
ruleBuilder := grammar.NewRuleBuilder(
130+
storages.SegmentStorage,
131+
storages.RuleBasedSegmentsStorage,
132+
storages.LargeSegmentStorage,
133+
adminCommon.ProducerFeatureFlagsRules,
134+
adminCommon.ProducerRuleBasedSegmentRules,
135+
logger,
136+
nil)
137+
128138
workers := synchronizer.Workers{
129-
// TODO add ruleBasedSegmentStorage, ruleBuilder, sdkOverrides
130-
SplitUpdater: split.NewSplitUpdater(storages.SplitStorage, nil, splitAPI.SplitFetcher, logger, syncTelemetryStorage, appMonitor, flagSetsFilter, grammar.RuleBuilder{}, false, cfg.FlagSpecVersion),
131-
// TODO add ruleBasedSegmentStorage
132-
SegmentUpdater: segment.NewSegmentUpdater(storages.SplitStorage, storages.SegmentStorage, nil, splitAPI.SegmentFetcher,
139+
// TODO add sdkOverrides
140+
SplitUpdater: split.NewSplitUpdater(storages.SplitStorage, storages.RuleBasedSegmentsStorage, splitAPI.SplitFetcher, logger, syncTelemetryStorage, appMonitor, flagSetsFilter, ruleBuilder, false, cfg.FlagSpecVersion),
141+
SegmentUpdater: segment.NewSegmentUpdater(storages.SplitStorage, storages.SegmentStorage, storages.RuleBasedSegmentsStorage, splitAPI.SegmentFetcher,
133142
logger, syncTelemetryStorage, appMonitor),
134143
ImpressionsCountRecorder: impressionscount.NewRecorderSingle(impressionsCounter, splitAPI.ImpressionRecorder,
135144
metadata, logger, syncTelemetryStorage),

splitio/proxy/caching/workers.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,41 @@ import (
1717
// CacheAwareSplitSynchronizer wraps a SplitSynchronizer and flushes cache when an update happens
1818
type CacheAwareSplitSynchronizer struct {
1919
splitStorage storage.SplitStorage
20+
rbStorage storage.RuleBasedSegmentsStorage
2021
wrapped split.Updater
2122
cacheFlusher gincache.CacheFlusher
2223
}
2324

2425
// NewCacheAwareSplitSync constructs a split-sync wrapper that evicts cache on updates
2526
func NewCacheAwareSplitSync(
2627
splitStorage storage.SplitStorage,
28+
ruleBasedStorage storage.RuleBasedSegmentsStorage,
2729
splitFetcher service.SplitFetcher,
2830
logger logging.LoggerInterface,
2931
runtimeTelemetry storage.TelemetryRuntimeProducer,
3032
cacheFlusher gincache.CacheFlusher,
3133
appMonitor application.MonitorProducerInterface,
3234
flagSetsFilter flagsets.FlagSetFilter,
3335
specVersion string,
36+
ruleBuilder grammar.RuleBuilder,
3437
) *CacheAwareSplitSynchronizer {
3538
return &CacheAwareSplitSynchronizer{
36-
// TODO add ruleBasedSegmentStorage, ruleBuilder, increase FLAG SPEC when we support RUleBased
37-
wrapped: split.NewSplitUpdater(splitStorage, nil, splitFetcher, logger, runtimeTelemetry, appMonitor, flagSetsFilter, grammar.RuleBuilder{}, false, specVersion),
39+
wrapped: split.NewSplitUpdater(splitStorage, ruleBasedStorage, splitFetcher, logger, runtimeTelemetry, appMonitor, flagSetsFilter, ruleBuilder, false, specVersion),
3840
splitStorage: splitStorage,
41+
rbStorage: ruleBasedStorage,
3942
cacheFlusher: cacheFlusher,
4043
}
4144
}
4245

4346
// SynchronizeSplits synchronizes feature flags and if something changes, purges the cache appropriately
4447
func (c *CacheAwareSplitSynchronizer) SynchronizeSplits(till *int64) (*split.UpdateResult, error) {
4548
previous, _ := c.splitStorage.ChangeNumber()
49+
previousRB, _ := c.rbStorage.ChangeNumber()
50+
4651
result, err := c.wrapped.SynchronizeSplits(till)
47-
if current, _ := c.splitStorage.ChangeNumber(); current > previous || (previous != -1 && current == -1) {
52+
current, _ := c.splitStorage.ChangeNumber()
53+
currentRB, _ := c.rbStorage.ChangeNumber()
54+
if current > previous || (previous != -1 && current == -1) || currentRB > previousRB || (previousRB != -1 && currentRB == -1) {
4855
// if the changenumber was updated, evict splitChanges responses from cache
4956
c.cacheFlusher.EvictBySurrogate(SplitSurrogate)
5057
}
@@ -61,8 +68,12 @@ func (c *CacheAwareSplitSynchronizer) LocalKill(splitName string, defaultTreatme
6168
// SynchronizeFeatureFlags synchronizes feature flags and if something changes, purges the cache appropriately
6269
func (c *CacheAwareSplitSynchronizer) SynchronizeFeatureFlags(ffChange *dtos.SplitChangeUpdate) (*split.UpdateResult, error) {
6370
previous, _ := c.splitStorage.ChangeNumber()
71+
previousRB, _ := c.rbStorage.ChangeNumber()
72+
6473
result, err := c.wrapped.SynchronizeFeatureFlags(ffChange)
65-
if current, _ := c.splitStorage.ChangeNumber(); current > previous || (previous != -1 && current == -1) {
74+
current, _ := c.splitStorage.ChangeNumber()
75+
currentRB, _ := c.rbStorage.ChangeNumber()
76+
if current > previous || (previous != -1 && current == -1) || currentRB > previousRB || (previousRB != -1 && currentRB == -1) {
6677
// if the changenumber was updated, evict splitChanges responses from cache
6778
c.cacheFlusher.EvictBySurrogate(SplitSurrogate)
6879
}
@@ -81,15 +92,15 @@ type CacheAwareSegmentSynchronizer struct {
8192
func NewCacheAwareSegmentSync(
8293
splitStorage storage.SplitStorage,
8394
segmentStorage storage.SegmentStorage,
95+
ruleBasedStorage storage.RuleBasedSegmentsStorage,
8496
segmentFetcher service.SegmentFetcher,
8597
logger logging.LoggerInterface,
8698
runtimeTelemetry storage.TelemetryRuntimeProducer,
8799
cacheFlusher gincache.CacheFlusher,
88100
appMonitor application.MonitorProducerInterface,
89101
) *CacheAwareSegmentSynchronizer {
90102
return &CacheAwareSegmentSynchronizer{
91-
// TODO add ruleBasedSegmentStorage
92-
wrapped: segment.NewSegmentUpdater(splitStorage, segmentStorage, nil, segmentFetcher, logger, runtimeTelemetry, appMonitor),
103+
wrapped: segment.NewSegmentUpdater(splitStorage, segmentStorage, ruleBasedStorage, segmentFetcher, logger, runtimeTelemetry, appMonitor),
93104
cacheFlusher: cacheFlusher,
94105
splitStorage: splitStorage,
95106
segmentStorage: segmentStorage,

splitio/proxy/conf/sections.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type Main struct {
2222
Logging conf.Logging `json:"logging" s-nested:"true"`
2323
Healthcheck Healthcheck `json:"healthcheck" s-nested:"true"`
2424
Observability Observability `json:"observability" s-nested:"true"`
25-
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.2" s-desc:"Spec version for flags"`
25+
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.3" s-desc:"Spec version for flags"`
2626
}
2727

2828
// BuildAdvancedConfig generates a commons-compatible advancedconfig with default + overriden parameters

splitio/proxy/controllers/sdk.go

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,15 @@ import (
2525

2626
// SdkServerController bundles all request handler for sdk-server apis
2727
type SdkServerController struct {
28-
logger logging.LoggerInterface
29-
fetcher service.SplitFetcher
30-
proxySplitStorage storage.ProxySplitStorage
31-
proxySegmentStorage storage.ProxySegmentStorage
32-
fsmatcher flagsets.FlagSetMatcher
33-
versionFilter specs.SplitVersionFilter
34-
largeSegmentStorage cmnStorage.LargeSegmentsStorage
35-
specVersion string
28+
logger logging.LoggerInterface
29+
fetcher service.SplitFetcher
30+
proxySplitStorage storage.ProxySplitStorage
31+
proxyRBSegmentStorage storage.ProxyRuleBasedSegmentsStorage
32+
proxySegmentStorage storage.ProxySegmentStorage
33+
fsmatcher flagsets.FlagSetMatcher
34+
versionFilter specs.SplitVersionFilter
35+
largeSegmentStorage cmnStorage.LargeSegmentsStorage
36+
specVersion string
3637
}
3738

3839
// NewSdkServerController instantiates a new sdk server controller
@@ -41,19 +42,21 @@ func NewSdkServerController(
4142
fetcher service.SplitFetcher,
4243
proxySplitStorage storage.ProxySplitStorage,
4344
proxySegmentStorage storage.ProxySegmentStorage,
45+
proxyRBSegmentStorage storage.ProxyRuleBasedSegmentsStorage,
4446
fsmatcher flagsets.FlagSetMatcher,
4547
largeSegmentStorage cmnStorage.LargeSegmentsStorage,
4648
specVersion string,
4749
) *SdkServerController {
4850
return &SdkServerController{
49-
logger: logger,
50-
fetcher: fetcher,
51-
proxySplitStorage: proxySplitStorage,
52-
proxySegmentStorage: proxySegmentStorage,
53-
fsmatcher: fsmatcher,
54-
versionFilter: specs.NewSplitVersionFilter(),
55-
largeSegmentStorage: largeSegmentStorage,
56-
specVersion: specVersion,
51+
logger: logger,
52+
fetcher: fetcher,
53+
proxySplitStorage: proxySplitStorage,
54+
proxySegmentStorage: proxySegmentStorage,
55+
proxyRBSegmentStorage: proxyRBSegmentStorage,
56+
fsmatcher: fsmatcher,
57+
versionFilter: specs.NewSplitVersionFilter(),
58+
largeSegmentStorage: largeSegmentStorage,
59+
specVersion: specVersion,
5760
}
5861
}
5962

@@ -107,6 +110,11 @@ func (c *SdkServerController) SplitChanges(ctx *gin.Context) {
107110
since = -1
108111
}
109112

113+
rbsince, err := strconv.ParseInt(ctx.DefaultQuery("rbSince", "-1"), 10, 64)
114+
if err != nil {
115+
rbsince = -1
116+
}
117+
110118
var rawSets []string
111119
if fq, ok := ctx.GetQuery("sets"); ok {
112120
rawSets = strings.Split(fq, ",")
@@ -116,9 +124,9 @@ func (c *SdkServerController) SplitChanges(ctx *gin.Context) {
116124
c.logger.Warning(fmt.Sprintf("SDK [%s] is sending flagsets unordered or with duplicates.", ctx.Request.Header.Get("SplitSDKVersion")))
117125
}
118126

119-
c.logger.Debug(fmt.Sprintf("SDK Fetches Feature Flags Since: %d", since))
127+
c.logger.Debug(fmt.Sprintf("SDK Fetches Feature Flags Since: %d, RBSince: %d", since, rbsince))
120128

121-
splits, err := c.fetchSplitChangesSince(since, sets)
129+
rules, err := c.fetchRulesSince(since, rbsince, sets)
122130
if err != nil {
123131
c.logger.Error("error fetching splitChanges payload from storage: ", err)
124132
ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
@@ -133,9 +141,23 @@ func (c *SdkServerController) SplitChanges(ctx *gin.Context) {
133141
return
134142
}
135143

136-
splits.Splits = c.patchUnsupportedMatchers(splits.Splits, spec)
144+
rules.FeatureFlags.Splits = c.patchUnsupportedMatchers(rules.FeatureFlags.Splits, spec)
137145

138-
ctx.JSON(http.StatusOK, splits)
146+
if spec == specs.FLAG_V1_3 {
147+
fmt.Println("1.3 1.3 1.3 1.3 1.3 ")
148+
fmt.Println("cantidad de ff:", len(rules.FeatureFlags.Splits), rules.FeatureFlags.Since, rules.FeatureFlags.Till)
149+
fmt.Println("cantidad de rb:", len(rules.RuleBasedSegments.RuleBasedSegments), rules.RuleBasedSegments.Since, rules.RuleBasedSegments.Till)
150+
ctx.JSON(http.StatusOK, rules)
151+
ctx.Set(caching.SurrogateContextKey, []string{caching.SplitSurrogate})
152+
ctx.Set(caching.StickyContextKey, true)
153+
return
154+
}
155+
fmt.Println("otra otra otra otra")
156+
ctx.JSON(http.StatusOK, dtos.SplitChangesDTO{
157+
Splits: rules.FeatureFlags.Splits,
158+
Since: rules.FeatureFlags.Since,
159+
Till: rules.FeatureFlags.Till,
160+
})
139161
ctx.Set(caching.SurrogateContextKey, []string{caching.SplitSurrogate})
140162
ctx.Set(caching.StickyContextKey, true)
141163
}
@@ -187,26 +209,49 @@ func (c *SdkServerController) MySegments(ctx *gin.Context) {
187209
ctx.Set(caching.SurrogateContextKey, caching.MakeSurrogateForMySegments(mySegments))
188210
}
189211

190-
func (c *SdkServerController) fetchSplitChangesSince(since int64, sets []string) (*dtos.SplitChangesDTO, error) {
212+
func (c *SdkServerController) fetchRulesSince(since int64, rbsince int64, sets []string) (*dtos.RuleChangesDTO, error) {
213+
fmt.Println("split change since: ", since)
191214
splits, err := c.proxySplitStorage.ChangesSince(since, sets)
192-
if err == nil {
193-
return splits, nil
215+
fmt.Println("split result: ", splits, err)
216+
fmt.Println("rule baseed since: ", rbsince)
217+
rbs, rbsErr := c.proxyRBSegmentStorage.ChangesSince(rbsince)
218+
fmt.Println("rulebased result: ", rbs, rbsErr)
219+
if err == nil && rbsErr == nil {
220+
return &dtos.RuleChangesDTO{
221+
FeatureFlags: dtos.FeatureFlagsDTO{
222+
Splits: splits.Splits,
223+
Till: splits.Till,
224+
Since: splits.Since,
225+
},
226+
RuleBasedSegments: *rbs,
227+
}, err
194228
}
195-
if !errors.Is(err, storage.ErrSinceParamTooOld) {
229+
if err != nil && !errors.Is(err, storage.ErrSinceParamTooOld) {
196230
return nil, fmt.Errorf("unexpected error fetching feature flag changes from storage: %w", err)
197231
}
198232

233+
if rbsErr != nil && !errors.Is(rbsErr, storage.ErrSinceParamTooOld) {
234+
return nil, fmt.Errorf("unexpected error fetching rule-based segments changes from storage: %w", rbsErr)
235+
}
236+
199237
// perform a fetch to the BE using the supplied `since`, have the storage process it's response &, retry
200238
// TODO(mredolatti): implement basic collapsing here to avoid flooding the BE with requests
201-
fetchOptions := service.MakeFlagRequestParams().WithSpecVersion(common.StringRef(c.specVersion)).WithChangeNumber(since).WithFlagSetsFilter(strings.Join(sets, ",")) // at this point the sets have been sanitized & sorted
239+
fetchOptions := service.MakeFlagRequestParams().WithSpecVersion(common.StringRef(c.specVersion)).WithChangeNumber(since).WithChangeNumberRB(rbsince).WithFlagSetsFilter(strings.Join(sets, ",")) // at this point the sets have been sanitized & sorted
202240
ruleChanges, err := c.fetcher.Fetch(fetchOptions)
203241
if err != nil {
204242
return nil, err
205243
}
206-
return &dtos.SplitChangesDTO{
207-
Since: ruleChanges.FFSince(),
208-
Till: ruleChanges.FFTill(),
209-
Splits: ruleChanges.FeatureFlags(),
244+
return &dtos.RuleChangesDTO{
245+
FeatureFlags: dtos.FeatureFlagsDTO{
246+
Splits: ruleChanges.FeatureFlags(),
247+
Till: ruleChanges.FFTill(),
248+
Since: ruleChanges.FFSince(),
249+
},
250+
RuleBasedSegments: dtos.RuleBasedSegmentsDTO{
251+
RuleBasedSegments: ruleChanges.RuleBasedSegments(),
252+
Till: ruleChanges.RBTill(),
253+
Since: ruleChanges.RBSince(),
254+
},
210255
}, nil
211256
}
212257

0 commit comments

Comments
 (0)