Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
a60ac6e
Updated commons
nmayorsplit Oct 16, 2025
2807f73
Updated with last changes from main
nmayorsplit Oct 16, 2025
2ea34a2
Merge pull request #237 from splitio/FME-10531
mmelograno Oct 16, 2025
582ac49
deps
mmelograno Oct 16, 2025
10ca8c1
Updated last changes from go-commos
nmayorsplit Oct 16, 2025
518d483
Merge pull request #239 from splitio/FME-10531
mmelograno Oct 16, 2025
a53f5dd
Updated version
nmayorsplit Oct 16, 2025
836c3fb
Updated commons version
nmayorsplit Oct 20, 2025
dfb2c70
Update commons to v8
nmayorsplit Oct 21, 2025
27369f8
Updated version
nmayorsplit Oct 21, 2025
252e3ec
Updated go commons
nmayorsplit Oct 22, 2025
2de0a18
Updated commons version
nmayorsplit Oct 22, 2025
6f4edcc
Added rb segment storage for redis
nmayorsplit Oct 24, 2025
981022e
Updated commons version
nmayorsplit Oct 24, 2025
107e033
Updated version
nmayorsplit Oct 24, 2025
1aa9a24
Updated tests for rule-based and redis
nmayorsplit Oct 27, 2025
5a118a1
Updated tests for redis
nmayorsplit Oct 27, 2025
82e4e72
Updated go commons version
nmayorsplit Oct 28, 2025
a354535
Updated commons with last changes
nmayorsplit Oct 30, 2025
bc4e9ac
Updated version to rc5
nmayorsplit Oct 30, 2025
da8da40
Updated commons version
nmayorsplit Nov 3, 2025
53ad387
Updated version
nmayorsplit Nov 3, 2025
8fc0806
Updated common version
nmayorsplit Nov 6, 2025
31803dc
Updated version and changelogs
nmayorsplit Nov 10, 2025
4c47bea
Updated common version to v8.0.0
nmayorsplit Nov 10, 2025
a66ed77
Merge branch 'main' into spec-proxy
mmelograno Nov 10, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
6.8.1 (Nov 10, 2025)
- Fixed to use an old proxy with 1.3 spec.

6.8.0 (Sep 26, 2025)
- Added support for rule-based segments. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK.
- Added support for feature flag prerequisites. This allows customers to define dependency conditions between flags, which are evaluated before any allowlists or targeting rules.
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/splitio/go-client/v6
go 1.18

require (
github.com/splitio/go-split-commons/v7 v7.0.1-0.20250930213118-b0b22c397fc4
github.com/splitio/go-toolkit/v5 v5.4.1-0.20250930172659-38274b802d99
github.com/splitio/go-split-commons/v8 v8.0.0
github.com/splitio/go-toolkit/v5 v5.4.1
github.com/stretchr/testify v1.11.1
)

Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/redis/go-redis/v9 v9.0.4 h1:FC82T+CHJ/Q/PdyLW++GeCO+Ol59Y4T7R4jbgjvktgc=
github.com/redis/go-redis/v9 v9.0.4/go.mod h1:WqMKv5vnQbRuZstUwxQI195wHy+t4PuXDOjzMvcuQHk=
github.com/splitio/go-split-commons/v7 v7.0.1-0.20250930213118-b0b22c397fc4 h1:OK9LLRmEpLghXM5paCrR9zFXTuYTdoiP2P2apwW3C9E=
github.com/splitio/go-split-commons/v7 v7.0.1-0.20250930213118-b0b22c397fc4/go.mod h1:Lsj2n1zm88laFRu+JhlNeXW0x1ndtjQ1H21rLhRFfOs=
github.com/splitio/go-toolkit/v5 v5.4.1-0.20250930172659-38274b802d99 h1:rQo355F9JbdyTMz2X5MU+FeRvkT6rvD1n+GnXdJr33A=
github.com/splitio/go-toolkit/v5 v5.4.1-0.20250930172659-38274b802d99/go.mod h1:SifzysrOVDbzMcOE8zjX02+FG5az4FrR3Us/i5SeStw=
github.com/splitio/go-split-commons/v8 v8.0.0 h1:wLk5eT6WU2LfxtaWG3ZHlTbNMGWP2eYsZTb1o+tFpkI=
github.com/splitio/go-split-commons/v8 v8.0.0/go.mod h1:vgRGPn0s4RC9/zp1nIn4KeeIEj/K3iXE2fxYQbCk/WI=
github.com/splitio/go-toolkit/v5 v5.4.1 h1:srTyvDBJZMUcJ/KiiQDMyjCuELVgTBh2TGRVn0sOXEE=
github.com/splitio/go-toolkit/v5 v5.4.1/go.mod h1:SifzysrOVDbzMcOE8zjX02+FG5az4FrR3Us/i5SeStw=
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
Expand Down
14 changes: 7 additions & 7 deletions splitio/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ import (
"github.com/splitio/go-client/v6/splitio/conf"
impressionlistener "github.com/splitio/go-client/v6/splitio/impressionListener"

"github.com/splitio/go-split-commons/v7/dtos"
"github.com/splitio/go-split-commons/v7/engine/evaluator"
"github.com/splitio/go-split-commons/v7/engine/evaluator/impressionlabels"
"github.com/splitio/go-split-commons/v7/flagsets"
"github.com/splitio/go-split-commons/v7/provisional"
"github.com/splitio/go-split-commons/v7/storage"
"github.com/splitio/go-split-commons/v7/telemetry"
"github.com/splitio/go-split-commons/v8/dtos"
"github.com/splitio/go-split-commons/v8/engine/evaluator"
"github.com/splitio/go-split-commons/v8/engine/evaluator/impressionlabels"
"github.com/splitio/go-split-commons/v8/flagsets"
"github.com/splitio/go-split-commons/v8/provisional"
"github.com/splitio/go-split-commons/v8/storage"
"github.com/splitio/go-split-commons/v8/telemetry"
"github.com/splitio/go-toolkit/v5/logging"
)

Expand Down
188 changes: 151 additions & 37 deletions splitio/client/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,26 @@ import (
"github.com/splitio/go-client/v6/splitio"
"github.com/splitio/go-client/v6/splitio/conf"
impressionlistener "github.com/splitio/go-client/v6/splitio/impressionListener"

commonsCfg "github.com/splitio/go-split-commons/v7/conf"
"github.com/splitio/go-split-commons/v7/dtos"
"github.com/splitio/go-split-commons/v7/engine/evaluator"
"github.com/splitio/go-split-commons/v7/engine/evaluator/impressionlabels"
evaluatorMock "github.com/splitio/go-split-commons/v7/engine/evaluator/mocks"
"github.com/splitio/go-split-commons/v7/healthcheck/application"
"github.com/splitio/go-split-commons/v7/provisional"
"github.com/splitio/go-split-commons/v7/provisional/strategy"
authMocks "github.com/splitio/go-split-commons/v7/service/mocks"
"github.com/splitio/go-split-commons/v7/storage"
"github.com/splitio/go-split-commons/v7/storage/inmemory"
"github.com/splitio/go-split-commons/v7/storage/inmemory/mutexqueue"
"github.com/splitio/go-split-commons/v7/storage/mocks"
"github.com/splitio/go-split-commons/v7/storage/redis"
"github.com/splitio/go-split-commons/v7/synchronizer"
syncMock "github.com/splitio/go-split-commons/v7/synchronizer/mocks"
"github.com/splitio/go-split-commons/v7/telemetry"
"github.com/splitio/go-split-commons/v7/util"
"github.com/stretchr/testify/assert"

commonsCfg "github.com/splitio/go-split-commons/v8/conf"
"github.com/splitio/go-split-commons/v8/dtos"
"github.com/splitio/go-split-commons/v8/engine/evaluator"
"github.com/splitio/go-split-commons/v8/engine/evaluator/impressionlabels"
evaluatorMock "github.com/splitio/go-split-commons/v8/engine/evaluator/mocks"
"github.com/splitio/go-split-commons/v8/healthcheck/application"
"github.com/splitio/go-split-commons/v8/provisional"
"github.com/splitio/go-split-commons/v8/provisional/strategy"
authMocks "github.com/splitio/go-split-commons/v8/service/mocks"
"github.com/splitio/go-split-commons/v8/storage"
"github.com/splitio/go-split-commons/v8/storage/inmemory"
"github.com/splitio/go-split-commons/v8/storage/inmemory/mutexqueue"
"github.com/splitio/go-split-commons/v8/storage/mocks"
"github.com/splitio/go-split-commons/v8/storage/redis"
"github.com/splitio/go-split-commons/v8/synchronizer"
syncMock "github.com/splitio/go-split-commons/v8/synchronizer/mocks"
"github.com/splitio/go-split-commons/v8/telemetry"
"github.com/splitio/go-split-commons/v8/util"

"github.com/splitio/go-toolkit/v5/datastructures/set"
"github.com/splitio/go-toolkit/v5/logging"
Expand Down Expand Up @@ -1005,26 +1006,30 @@ func TestBlockUntilReadyInMemoryOk(t *testing.T) {
mockedSplit3 := dtos.SplitDTO{Name: "split3", Killed: true, Status: "INACTIVE"}

sdkServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(3 * time.Second)
if r.URL.Path != "/splitChanges" || r.Method != "GET" {
t.Error("Invalid request. Should be GET to /splitChanges")
}
switch r.URL.Path {
case "/version":
w.WriteHeader(http.StatusOK)
case "/splitChanges":
time.Sleep(3 * time.Second)
splitChanges := dtos.RuleChangesDTO{
FeatureFlags: dtos.FeatureFlagsDTO{
Splits: []dtos.SplitDTO{mockedSplit1, mockedSplit2, mockedSplit3},
Since: 3,
Till: 3,
},
}

splitChanges := dtos.SplitChangesDTO{
FeatureFlags: dtos.FeatureFlagsDTO{
Splits: []dtos.SplitDTO{mockedSplit1, mockedSplit2, mockedSplit3},
Since: 3,
Till: 3,
},
}
raw, err := json.Marshal(splitChanges)
if err != nil {
t.Error("Error building json")
return
}

raw, err := json.Marshal(splitChanges)
if err != nil {
t.Error("Error building json")
return
w.Write(raw)
default:
t.Error("Unexpected path")
}

w.Write(raw)
}))
defer sdkServer.Close()

Expand Down Expand Up @@ -1150,7 +1155,7 @@ func TestBlockUntilReadyInMemoryOk(t *testing.T) {

err = client.BlockUntilReady(2)
if err != nil {
t.Error("Wrong message error")
t.Error("Wrong message error", err.Error())
}

if !client.factory.IsReady() || !manager.factory.IsReady() {
Expand Down Expand Up @@ -2443,7 +2448,7 @@ func TestTelemetryMemory(t *testing.T) {

sdkServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
time.Sleep(100 * time.Millisecond)
splitChanges := dtos.SplitChangesDTO{
splitChanges := dtos.RuleChangesDTO{
FeatureFlags: dtos.FeatureFlagsDTO{
Splits: []dtos.SplitDTO{
{Name: "split1", Killed: true, Status: "ACTIVE", DefaultTreatment: "on"},
Expand Down Expand Up @@ -3111,6 +3116,115 @@ func TestUnsupportedandSemverMatcherRedis(t *testing.T) {
}
}

var splitRuleBased = &dtos.SplitDTO{
Algo: 2,
ChangeNumber: 1494593336752,
DefaultTreatment: "off",
Killed: false,
Name: "rbsplit",
Seed: -1992295819,
Status: "ACTIVE",
TrafficAllocation: 100,
TrafficAllocationSeed: -285565213,
TrafficTypeName: "user",
Configurations: map[string]string{"on": "{\"color\": \"blue\",\"size\": 13}"},
Conditions: []dtos.ConditionDTO{
{
ConditionType: "ROLLOUT",
Label: "default rule",
MatcherGroup: dtos.MatcherGroupDTO{
Combiner: "AND",
Matchers: []dtos.MatcherDTO{
{
KeySelector: &dtos.KeySelectorDTO{
TrafficType: "user",
},
MatcherType: "IN_RULE_BASED_SEGMENT",
UserDefinedSegment: &dtos.UserDefinedSegmentMatcherDataDTO{
SegmentName: "rbsegment1",
},
Negate: false,
},
},
},
Partitions: []dtos.PartitionDTO{
{
Size: 100,
Treatment: "on",
},
{
Size: 0,
Treatment: "off",
},
},
},
},
}

var rbsegment1 = &dtos.RuleBasedSegmentDTO{
Name: "rbsegment1",
Conditions: []dtos.RuleBasedConditionDTO{
{
MatcherGroup: dtos.MatcherGroupDTO{
Combiner: "AND",
Matchers: []dtos.MatcherDTO{
{
KeySelector: &dtos.KeySelectorDTO{
TrafficType: "user",
Attribute: &attribute,
},
MatcherType: "EQUAL_TO_SEMVER",
String: &semver,
Whitelist: nil,
Negate: false,
},
},
},
},
},
TrafficTypeName: "user",
}

func TestRuleBasedSegmentRedis(t *testing.T) {
redisConfig := &commonsCfg.RedisConfig{
Host: "localhost",
Port: 6379,
Password: "",
Prefix: "test-prefix-rulebased",
}

prefixedClient, _ := redis.NewRedisClient(redisConfig, logging.NewLogger(&logging.LoggerOptions{}))
// Clean redis
defer func() {
keys, _ := prefixedClient.Keys("test-prefix-rulebased*")
for _, k := range keys {
prefixedClient.Del(k)
}
}()
raw, _ := json.Marshal(*splitRuleBased)
prefixedClient.Set("SPLITIO.split.rbsplit", raw, 0)
rbraw, _ := json.Marshal(*rbsegment1)
prefixedClient.Set("SPLITIO.rbsegment.rbsegment1", rbraw, 0)

impTest := &ImpressionListenerTest{}
cfg := conf.Default()
cfg.LabelsEnabled = true
cfg.Advanced.ImpressionListener = impTest
cfg.ImpressionsMode = commonsCfg.ImpressionsModeOptimized
cfg.OperationMode = conf.RedisConsumer
cfg.Redis = *redisConfig

factory, _ := NewSplitFactory("test", cfg)
client := factory.Client()

// Calls treatments to generate one valid impression
attributes := make(map[string]interface{})
attributes["version"] = "3.4.5"
evaluation := client.Treatment("user1", "rbsplit", attributes)
assert.Equal(t, "on", evaluation, "evaluation for rbsplit should be on")
client.Destroy()
}

func TestPrerequisites(t *testing.T) {
var isDestroyCalled = false
var splitsMock, _ = ioutil.ReadFile("../../testdata/splits_mock_5.json")
Expand Down
54 changes: 28 additions & 26 deletions splitio/client/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,30 @@ import (
impressionlistener "github.com/splitio/go-client/v6/splitio/impressionListener"
"github.com/splitio/go-client/v6/splitio/impressions"

config "github.com/splitio/go-split-commons/v7/conf"
"github.com/splitio/go-split-commons/v7/dtos"
"github.com/splitio/go-split-commons/v7/engine"
"github.com/splitio/go-split-commons/v7/engine/evaluator"
"github.com/splitio/go-split-commons/v7/engine/grammar"
"github.com/splitio/go-split-commons/v7/flagsets"
"github.com/splitio/go-split-commons/v7/healthcheck/application"
"github.com/splitio/go-split-commons/v7/provisional"
"github.com/splitio/go-split-commons/v7/provisional/strategy"
"github.com/splitio/go-split-commons/v7/service/api"
"github.com/splitio/go-split-commons/v7/service/api/specs"
"github.com/splitio/go-split-commons/v7/service/local"
"github.com/splitio/go-split-commons/v7/storage"
"github.com/splitio/go-split-commons/v7/storage/inmemory"
"github.com/splitio/go-split-commons/v7/storage/inmemory/mutexmap"
"github.com/splitio/go-split-commons/v7/storage/inmemory/mutexqueue"
"github.com/splitio/go-split-commons/v7/storage/mocks"
"github.com/splitio/go-split-commons/v7/storage/redis"
"github.com/splitio/go-split-commons/v7/synchronizer"
"github.com/splitio/go-split-commons/v7/synchronizer/worker/event"
"github.com/splitio/go-split-commons/v7/synchronizer/worker/segment"
"github.com/splitio/go-split-commons/v7/synchronizer/worker/split"
"github.com/splitio/go-split-commons/v7/tasks"
"github.com/splitio/go-split-commons/v7/telemetry"
config "github.com/splitio/go-split-commons/v8/conf"
"github.com/splitio/go-split-commons/v8/dtos"
"github.com/splitio/go-split-commons/v8/engine"
"github.com/splitio/go-split-commons/v8/engine/evaluator"
"github.com/splitio/go-split-commons/v8/engine/grammar"
"github.com/splitio/go-split-commons/v8/flagsets"
"github.com/splitio/go-split-commons/v8/healthcheck/application"
"github.com/splitio/go-split-commons/v8/provisional"
"github.com/splitio/go-split-commons/v8/provisional/strategy"
"github.com/splitio/go-split-commons/v8/service/api"
"github.com/splitio/go-split-commons/v8/service/api/specs"
"github.com/splitio/go-split-commons/v8/service/local"
"github.com/splitio/go-split-commons/v8/storage"
"github.com/splitio/go-split-commons/v8/storage/inmemory"
"github.com/splitio/go-split-commons/v8/storage/inmemory/mutexmap"
"github.com/splitio/go-split-commons/v8/storage/inmemory/mutexqueue"
"github.com/splitio/go-split-commons/v8/storage/mocks"
"github.com/splitio/go-split-commons/v8/storage/redis"
"github.com/splitio/go-split-commons/v8/synchronizer"
"github.com/splitio/go-split-commons/v8/synchronizer/worker/event"
"github.com/splitio/go-split-commons/v8/synchronizer/worker/segment"
"github.com/splitio/go-split-commons/v8/synchronizer/worker/split"
"github.com/splitio/go-split-commons/v8/tasks"
"github.com/splitio/go-split-commons/v8/telemetry"
"github.com/splitio/go-toolkit/v5/logging"
)

Expand Down Expand Up @@ -124,7 +124,7 @@ func (f *SplitFactory) IsReady() bool {

// initializates tasks for in-memory mode
func (f *SplitFactory) initializationManager(readyChannel chan int, flagSetsInvalid int64) {
go f.syncManager.StartBGSyng(readyChannel, f.cfg.Advanced.RetryEnabled, func() {
go f.syncManager.StartBGSync(readyChannel, f.cfg.Advanced.RetryEnabled, func() {
f.broadcastReadiness(sdkStatusReady, make([]string, 0), flagSetsInvalid)
})
}
Expand Down Expand Up @@ -296,10 +296,11 @@ func setupInMemoryFactory(

splitAPI := api.NewSplitAPI(apikey, advanced, logger, metadata)

isProxy := splitAPI.SplitFetcher.IsProxy()
evaluator := evaluator.NewEvaluator(splitsStorage, segmentsStorage, ruleBasedSegmentStorage, nil, engine.NewEngine(logger), logger, cfg.Advanced.FeatureFlagRules, cfg.Advanced.RuleBasedSegmentRules)
ruleBuilder := grammar.NewRuleBuilder(segmentsStorage, ruleBasedSegmentStorage, nil, cfg.Advanced.FeatureFlagRules, cfg.Advanced.RuleBasedSegmentRules, logger, evaluator)
workers := synchronizer.Workers{
SplitUpdater: split.NewSplitUpdater(splitsStorage, ruleBasedSegmentStorage, splitAPI.SplitFetcher, logger, telemetryStorage, dummyHC, flagSetFilter, ruleBuilder),
SplitUpdater: split.NewSplitUpdater(splitsStorage, ruleBasedSegmentStorage, splitAPI.SplitFetcher, logger, telemetryStorage, dummyHC, flagSetFilter, ruleBuilder, isProxy, advanced.FlagsSpecVersion),
SegmentUpdater: segment.NewSegmentUpdater(splitsStorage, segmentsStorage, ruleBasedSegmentStorage, splitAPI.SegmentFetcher, logger, telemetryStorage, dummyHC),
EventRecorder: event.NewEventRecorderSingle(eventsStorage, splitAPI.EventRecorder, logger, metadata, telemetryStorage),
TelemetryRecorder: telemetry.NewTelemetrySynchronizer(telemetryStorage, splitAPI.TelemetryRecorder, splitsStorage, segmentsStorage, logger, metadata, telemetryStorage),
Expand Down Expand Up @@ -404,6 +405,7 @@ func setupRedisFactory(apikey string, cfg *conf.SplitSdkConfig, logger logging.L
storages := sdkStorages{
splits: redis.NewSplitStorage(redisClient, logger, flagSetFilter),
segments: redis.NewSegmentStorage(redisClient, logger),
ruleBasedSegments: redis.NewRuleBasedStorage(redisClient, logger),
impressionsConsumer: impressionStorage,
impressions: impressionStorage,
events: redis.NewEventsStorage(redisClient, metadata, logger),
Expand Down
2 changes: 1 addition & 1 deletion splitio/client/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package client
import (
"testing"

"github.com/splitio/go-split-commons/v7/flagsets"
"github.com/splitio/go-split-commons/v8/flagsets"
"github.com/splitio/go-toolkit/v5/logging/mocks"

"github.com/stretchr/testify/assert"
Expand Down
4 changes: 2 additions & 2 deletions splitio/client/input_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import (
"strconv"
"strings"

"github.com/splitio/go-split-commons/v7/engine/evaluator/impressionlabels"
"github.com/splitio/go-split-commons/v7/storage"
"github.com/splitio/go-split-commons/v8/engine/evaluator/impressionlabels"
"github.com/splitio/go-split-commons/v8/storage"
"github.com/splitio/go-toolkit/v5/datastructures/set"
"github.com/splitio/go-toolkit/v5/logging"
)
Expand Down
Loading
Loading