Skip to content

Commit 71ca2eb

Browse files
authored
Merge pull request #504 from splitio/development
Release 8.3.0
2 parents 2c32af6 + 2b290bf commit 71ca2eb

File tree

74 files changed

+2628
-431
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+2628
-431
lines changed

CHANGES.txt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
CHANGES
2+
8.3.0 (Dec 11, 2023)
3+
- Added support for Flag Sets on the SDK, which enables grouping feature flags and interacting with the group rather than individually (more details in our documentation):
4+
- Added new variations of the get treatment methods to support evaluating flags in given flag set/s.
5+
- get_treatments_by_flag_set and get_treatments_by_flag_sets
6+
- get_treatments_with_config_by_flag_set and get_treatments_with_config_by_flag_sets
7+
- Added a new optional Split Filter configuration option. This allows the SDK and Split services to only synchronize the flags in the specified flag sets, avoiding unused or unwanted flags from being synced on the SDK instance, bringing all the benefits from a reduced payload.
8+
- Note: Only applicable when the SDK is in charge of the rollout data synchronization. When not applicable, the SDK will log a warning on init.
9+
- Added `default_treatment` and `sets` property to the `split_view` object returned by the `split` and `splits` methods of the SDK manager.
210

311
8.2.0 (Jul 18, 2023)
412
- Improved streaming architecture implementation to apply feature flag updates from the notification received which is now enhanced, improving efficiency and reliability of the whole update system.
@@ -60,10 +68,10 @@ CHANGES
6068

6169
7.2.1 (Oct 23, 2020)
6270
- Updated redis dependency to >= 4.2.2.
63-
- Updated ably error handling.
71+
- Updated ably error handling.
6472

6573
7.2.0 (Sep 25, 2020)
66-
- Added impressions dedupe logic to avoid sending duplicated impressions:
74+
- Added impressions dedupe logic to avoid sending duplicated impressions:
6775
- Added `OPTIMIZED` and `DEBUG` modes in order to enabling/disabling how impressions are going to be sent into Split servers,
6876
- `OPTIMIZED`: will send unique impressions in a timeframe in order to reduce how many times impressions are posted to Split.
6977
- `DEBUG`: will send every impression generated to Split.

lib/splitclient-rb.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
require 'splitclient-rb/cache/fetchers/split_fetcher'
1515
require 'splitclient-rb/cache/filter/bloom_filter'
1616
require 'splitclient-rb/cache/filter/filter_adapter'
17+
require 'splitclient-rb/cache/filter/flag_set_filter'
1718
require 'splitclient-rb/cache/hashers/impression_hasher'
1819
require 'splitclient-rb/cache/observers/impression_observer'
1920
require 'splitclient-rb/cache/observers/noop_impression_observer'
@@ -24,6 +25,8 @@
2425
require 'splitclient-rb/cache/repositories/impressions_repository'
2526
require 'splitclient-rb/cache/repositories/events/memory_repository'
2627
require 'splitclient-rb/cache/repositories/events/redis_repository'
28+
require 'splitclient-rb/cache/repositories/flag_sets/memory_repository'
29+
require 'splitclient-rb/cache/repositories/flag_sets/redis_repository'
2730
require 'splitclient-rb/cache/repositories/impressions/memory_repository'
2831
require 'splitclient-rb/cache/repositories/impressions/redis_repository'
2932
require 'splitclient-rb/cache/senders/impressions_formatter'
@@ -43,6 +46,7 @@
4346
require 'splitclient-rb/helpers/thread_helper'
4447
require 'splitclient-rb/helpers/decryption_helper'
4548
require 'splitclient-rb/helpers/util'
49+
require 'splitclient-rb/helpers/repository_helper'
4650
require 'splitclient-rb/split_factory'
4751
require 'splitclient-rb/split_factory_builder'
4852
require 'splitclient-rb/split_config'

lib/splitclient-rb/cache/fetchers/split_fetcher.rb

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,16 @@ def call
1717
fetch_splits
1818
return
1919
end
20-
20+
2121
splits_thread
2222
end
2323

2424
def fetch_splits(fetch_options = { cache_control_headers: false, till: nil })
2525
@semaphore.synchronize do
2626
data = splits_since(@splits_repository.get_change_number, fetch_options)
2727

28-
data[:splits] && data[:splits].each do |split|
29-
add_split_unless_archived(split)
30-
end
31-
28+
SplitIoClient::Helpers::RepositoryHelper.update_feature_flag_repository(@splits_repository, data[:splits], data[:till], @config)
3229
@splits_repository.set_segment_names(data[:segment_names])
33-
@splits_repository.set_change_number(data[:till])
34-
3530
@config.logger.debug("segments seen(#{data[:segment_names].length}): #{data[:segment_names].to_a}") if @config.debug_enabled
3631

3732
{ segment_names: data[:segment_names], success: true }
@@ -64,28 +59,6 @@ def splits_since(since, fetch_options = { cache_control_headers: false, till: ni
6459
splits_api.since(since, fetch_options)
6560
end
6661

67-
def add_split_unless_archived(split)
68-
if Engine::Models::Split.archived?(split)
69-
@config.logger.debug("Seeing archived feature flag #{split[:name]}") if @config.debug_enabled
70-
71-
remove_archived_split(split)
72-
else
73-
store_split(split)
74-
end
75-
end
76-
77-
def remove_archived_split(split)
78-
@config.logger.debug("removing feature flag from store(#{split})") if @config.debug_enabled
79-
80-
@splits_repository.remove_split(split)
81-
end
82-
83-
def store_split(split)
84-
@config.logger.debug("storing feature flag (#{split[:name]})") if @config.debug_enabled
85-
86-
@splits_repository.add_split(split)
87-
end
88-
8962
def splits_api
9063
@splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @config, @telemetry_runtime_producer)
9164
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# frozen_string_literal: true
2+
3+
require 'set'
4+
5+
module SplitIoClient
6+
module Cache
7+
module Filter
8+
class FlagSetsFilter
9+
def initialize(flag_sets = [])
10+
@flag_sets = Set.new(flag_sets)
11+
@should_filter = @flag_sets.any?
12+
end
13+
14+
def should_filter?
15+
@should_filter
16+
end
17+
18+
def flag_set_exist?(flag_set)
19+
return true unless @should_filter
20+
21+
if not flag_set.is_a?(String) or flag_set.empty?
22+
return false
23+
end
24+
25+
@flag_sets.intersection([flag_set]).any?
26+
end
27+
28+
def intersect?(flag_sets)
29+
return true unless @should_filter
30+
31+
if not flag_sets.is_a?(Array) or flag_sets.empty?
32+
return false
33+
end
34+
35+
@flag_sets.intersection(Set.new(flag_sets)).any?
36+
end
37+
end
38+
end
39+
end
40+
end
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
require 'concurrent'
2+
3+
module SplitIoClient
4+
module Cache
5+
module Repositories
6+
class MemoryFlagSetsRepository
7+
def initialize(flag_sets = [])
8+
@sets_feature_flag_map = {}
9+
flag_sets.each{ |flag_set| @sets_feature_flag_map[flag_set] = Set[] }
10+
end
11+
12+
def flag_set_exist?(flag_set)
13+
@sets_feature_flag_map.key?(flag_set)
14+
end
15+
16+
def get_flag_sets(flag_sets)
17+
to_return = Array.new
18+
flag_sets.each { |flag_set| to_return.concat(@sets_feature_flag_map[flag_set].to_a)}
19+
to_return.uniq
20+
end
21+
22+
def add_flag_set(flag_set)
23+
@sets_feature_flag_map[flag_set] = Set[] if !flag_set_exist?(flag_set)
24+
end
25+
26+
def remove_flag_set(flag_set)
27+
@sets_feature_flag_map.delete(flag_set) if flag_set_exist?(flag_set)
28+
end
29+
30+
def add_feature_flag_to_flag_set(flag_set, feature_flag)
31+
@sets_feature_flag_map[flag_set].add(feature_flag) if flag_set_exist?(flag_set)
32+
end
33+
34+
def remove_feature_flag_from_flag_set(flag_set, feature_flag)
35+
@sets_feature_flag_map[flag_set].delete(feature_flag) if flag_set_exist?(flag_set)
36+
end
37+
end
38+
end
39+
end
40+
end
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
require 'concurrent'
2+
3+
module SplitIoClient
4+
module Cache
5+
module Repositories
6+
class RedisFlagSetsRepository < Repository
7+
8+
def initialize(config)
9+
super(config)
10+
@adapter = SplitIoClient::Cache::Adapters::RedisAdapter.new(@config.redis_url)
11+
end
12+
13+
def flag_set_exist?(flag_set)
14+
@adapter.exists?(namespace_key(".flagSet.#{flag_set}"))
15+
end
16+
17+
def get_flag_sets(flag_sets)
18+
result = @adapter.redis.pipelined do |pipeline|
19+
flag_sets.each do |flag_set|
20+
pipeline.smembers(namespace_key(".flagSet.#{flag_set}"))
21+
end
22+
end
23+
to_return = Array.new
24+
result.each do |flag_set|
25+
flag_set.each { |feature_flag_name| to_return.push(feature_flag_name.to_s)}
26+
end
27+
to_return.uniq
28+
end
29+
30+
def add_flag_set(flag_set)
31+
# not implemented
32+
end
33+
34+
def remove_flag_set(flag_set)
35+
# not implemented
36+
end
37+
38+
def add_feature_flag_to_flag_set(flag_set, feature_flag)
39+
# not implemented
40+
end
41+
42+
def remove_feature_flag_from_flag_set(flag_set, feature_flag)
43+
# not implemented
44+
end
45+
46+
end
47+
end
48+
end
49+
end

0 commit comments

Comments
 (0)