Skip to content

Commit

Permalink
Merge pull request #504 from splitio/development
Browse files Browse the repository at this point in the history
Release 8.3.0
  • Loading branch information
chillaq authored Dec 11, 2023
2 parents 2c32af6 + 2b290bf commit 71ca2eb
Show file tree
Hide file tree
Showing 74 changed files with 2,628 additions and 431 deletions.
12 changes: 10 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
CHANGES
8.3.0 (Dec 11, 2023)
- 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):
- Added new variations of the get treatment methods to support evaluating flags in given flag set/s.
- get_treatments_by_flag_set and get_treatments_by_flag_sets
- get_treatments_with_config_by_flag_set and get_treatments_with_config_by_flag_sets
- 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.
- 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.
- Added `default_treatment` and `sets` property to the `split_view` object returned by the `split` and `splits` methods of the SDK manager.

8.2.0 (Jul 18, 2023)
- 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.
Expand Down Expand Up @@ -60,10 +68,10 @@ CHANGES

7.2.1 (Oct 23, 2020)
- Updated redis dependency to >= 4.2.2.
- Updated ably error handling.
- Updated ably error handling.

7.2.0 (Sep 25, 2020)
- Added impressions dedupe logic to avoid sending duplicated impressions:
- Added impressions dedupe logic to avoid sending duplicated impressions:
- Added `OPTIMIZED` and `DEBUG` modes in order to enabling/disabling how impressions are going to be sent into Split servers,
- `OPTIMIZED`: will send unique impressions in a timeframe in order to reduce how many times impressions are posted to Split.
- `DEBUG`: will send every impression generated to Split.
Expand Down
4 changes: 4 additions & 0 deletions lib/splitclient-rb.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
require 'splitclient-rb/cache/fetchers/split_fetcher'
require 'splitclient-rb/cache/filter/bloom_filter'
require 'splitclient-rb/cache/filter/filter_adapter'
require 'splitclient-rb/cache/filter/flag_set_filter'
require 'splitclient-rb/cache/hashers/impression_hasher'
require 'splitclient-rb/cache/observers/impression_observer'
require 'splitclient-rb/cache/observers/noop_impression_observer'
Expand All @@ -24,6 +25,8 @@
require 'splitclient-rb/cache/repositories/impressions_repository'
require 'splitclient-rb/cache/repositories/events/memory_repository'
require 'splitclient-rb/cache/repositories/events/redis_repository'
require 'splitclient-rb/cache/repositories/flag_sets/memory_repository'
require 'splitclient-rb/cache/repositories/flag_sets/redis_repository'
require 'splitclient-rb/cache/repositories/impressions/memory_repository'
require 'splitclient-rb/cache/repositories/impressions/redis_repository'
require 'splitclient-rb/cache/senders/impressions_formatter'
Expand All @@ -43,6 +46,7 @@
require 'splitclient-rb/helpers/thread_helper'
require 'splitclient-rb/helpers/decryption_helper'
require 'splitclient-rb/helpers/util'
require 'splitclient-rb/helpers/repository_helper'
require 'splitclient-rb/split_factory'
require 'splitclient-rb/split_factory_builder'
require 'splitclient-rb/split_config'
Expand Down
31 changes: 2 additions & 29 deletions lib/splitclient-rb/cache/fetchers/split_fetcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,16 @@ def call
fetch_splits
return
end

splits_thread
end

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

data[:splits] && data[:splits].each do |split|
add_split_unless_archived(split)
end

SplitIoClient::Helpers::RepositoryHelper.update_feature_flag_repository(@splits_repository, data[:splits], data[:till], @config)
@splits_repository.set_segment_names(data[:segment_names])
@splits_repository.set_change_number(data[:till])

@config.logger.debug("segments seen(#{data[:segment_names].length}): #{data[:segment_names].to_a}") if @config.debug_enabled

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

def add_split_unless_archived(split)
if Engine::Models::Split.archived?(split)
@config.logger.debug("Seeing archived feature flag #{split[:name]}") if @config.debug_enabled

remove_archived_split(split)
else
store_split(split)
end
end

def remove_archived_split(split)
@config.logger.debug("removing feature flag from store(#{split})") if @config.debug_enabled

@splits_repository.remove_split(split)
end

def store_split(split)
@config.logger.debug("storing feature flag (#{split[:name]})") if @config.debug_enabled

@splits_repository.add_split(split)
end

def splits_api
@splits_api ||= SplitIoClient::Api::Splits.new(@api_key, @config, @telemetry_runtime_producer)
end
Expand Down
40 changes: 40 additions & 0 deletions lib/splitclient-rb/cache/filter/flag_set_filter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# frozen_string_literal: true

require 'set'

module SplitIoClient
module Cache
module Filter
class FlagSetsFilter
def initialize(flag_sets = [])
@flag_sets = Set.new(flag_sets)
@should_filter = @flag_sets.any?
end

def should_filter?
@should_filter
end

def flag_set_exist?(flag_set)
return true unless @should_filter

if not flag_set.is_a?(String) or flag_set.empty?
return false
end

@flag_sets.intersection([flag_set]).any?
end

def intersect?(flag_sets)
return true unless @should_filter

if not flag_sets.is_a?(Array) or flag_sets.empty?
return false
end

@flag_sets.intersection(Set.new(flag_sets)).any?
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require 'concurrent'

module SplitIoClient
module Cache
module Repositories
class MemoryFlagSetsRepository
def initialize(flag_sets = [])
@sets_feature_flag_map = {}
flag_sets.each{ |flag_set| @sets_feature_flag_map[flag_set] = Set[] }
end

def flag_set_exist?(flag_set)
@sets_feature_flag_map.key?(flag_set)
end

def get_flag_sets(flag_sets)
to_return = Array.new
flag_sets.each { |flag_set| to_return.concat(@sets_feature_flag_map[flag_set].to_a)}
to_return.uniq
end

def add_flag_set(flag_set)
@sets_feature_flag_map[flag_set] = Set[] if !flag_set_exist?(flag_set)
end

def remove_flag_set(flag_set)
@sets_feature_flag_map.delete(flag_set) if flag_set_exist?(flag_set)
end

def add_feature_flag_to_flag_set(flag_set, feature_flag)
@sets_feature_flag_map[flag_set].add(feature_flag) if flag_set_exist?(flag_set)
end

def remove_feature_flag_from_flag_set(flag_set, feature_flag)
@sets_feature_flag_map[flag_set].delete(feature_flag) if flag_set_exist?(flag_set)
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'concurrent'

module SplitIoClient
module Cache
module Repositories
class RedisFlagSetsRepository < Repository

def initialize(config)
super(config)
@adapter = SplitIoClient::Cache::Adapters::RedisAdapter.new(@config.redis_url)
end

def flag_set_exist?(flag_set)
@adapter.exists?(namespace_key(".flagSet.#{flag_set}"))
end

def get_flag_sets(flag_sets)
result = @adapter.redis.pipelined do |pipeline|
flag_sets.each do |flag_set|
pipeline.smembers(namespace_key(".flagSet.#{flag_set}"))
end
end
to_return = Array.new
result.each do |flag_set|
flag_set.each { |feature_flag_name| to_return.push(feature_flag_name.to_s)}
end
to_return.uniq
end

def add_flag_set(flag_set)
# not implemented
end

def remove_flag_set(flag_set)
# not implemented
end

def add_feature_flag_to_flag_set(flag_set, feature_flag)
# not implemented
end

def remove_feature_flag_from_flag_set(flag_set, feature_flag)
# not implemented
end

end
end
end
end
Loading

0 comments on commit 71ca2eb

Please sign in to comment.