diff --git a/lib/splitclient-rb.rb b/lib/splitclient-rb.rb index 5f4ebcc9..e30bfed0 100644 --- a/lib/splitclient-rb.rb +++ b/lib/splitclient-rb.rb @@ -66,6 +66,7 @@ require 'splitclient-rb/engine/common/impressions_counter' require 'splitclient-rb/engine/common/impressions_manager' require 'splitclient-rb/engine/common/noop_impressions_counter' +require 'splitclient-rb/engine/events/events_manager_config.rb' require 'splitclient-rb/engine/parser/condition' require 'splitclient-rb/engine/parser/partition' require 'splitclient-rb/engine/parser/evaluator' @@ -112,6 +113,10 @@ require 'splitclient-rb/engine/models/evaluation_options' require 'splitclient-rb/engine/models/fallback_treatment.rb' require 'splitclient-rb/engine/models/fallback_treatments_configuration.rb' +require 'splitclient-rb/engine/models/events_metadata.rb' +require 'splitclient-rb/engine/models/sdk_event_type.rb' +require 'splitclient-rb/engine/models/sdk_event.rb' +require 'splitclient-rb/engine/models/sdk_internal_event.rb' require 'splitclient-rb/engine/auth_api_client' require 'splitclient-rb/engine/back_off' require 'splitclient-rb/engine/fallback_treatment_calculator.rb' diff --git a/lib/splitclient-rb/engine/events/events_manager_config.rb b/lib/splitclient-rb/engine/events/events_manager_config.rb new file mode 100644 index 00000000..03577af9 --- /dev/null +++ b/lib/splitclient-rb/engine/events/events_manager_config.rb @@ -0,0 +1,87 @@ +# frozen_string_literal: true + +module SplitIoClient::Engine::Events + class EventsManagerConfig + attr_accessor :require_all, :prerequisites, :require_any, :suppressed_by, :execution_limits, :evaluation_order + + def initialize + @require_all = get_require_all + @prerequisites = get_prerequisites + @require_any = get_require_any + @suppressed_by = get_suppressed_by + @execution_limits = get_execution_limits + @evaluation_order = get_sorted_events + end + + private + + def get_require_all + return { + SplitIoClient::Engine::Models::SdkEvent::SDK_READY => Set.new([SplitIoClient::Engine::Models::SdkInternalEvent::SDK_READY]) + } + end + + def get_prerequisites + return { + SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => Set.new([SplitIoClient::Engine::Models::SdkEvent::SDK_READY]) + } + end + + def get_require_any + return { + SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => Set.new([SplitIoClient::Engine::Models::SdkInternalEvent::FLAG_KILLED_NOTIFICATION, SplitIoClient::Engine::Models::SdkInternalEvent::FLAGS_UPDATED, + SplitIoClient::Engine::Models::SdkInternalEvent::RB_SEGMENTS_UPDATED, SplitIoClient::Engine::Models::SdkInternalEvent::SEGMENTS_UPDATED]) + } + end + + def get_suppressed_by + return {} + end + + def get_execution_limits + return { + SplitIoClient::Engine::Models::SdkEvent::SDK_READY => 1, + SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE => -1 + } + end + + def get_sorted_events + sorted_events = [] + for sdk_event in [SplitIoClient::Engine::Models::SdkEvent::SDK_READY, SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE] + sorted_events = dfs_recursive(sdk_event, sorted_events) + end + + return sorted_events + end + + def dfs_recursive(sdk_event, added) + return added if added.include?(sdk_event) + + get_dependencies(sdk_event).each do |dependent_event| + added = dfs_recursive(dependent_event, added) + end + + added.push(sdk_event) + return added + end + + def get_dependencies(sdk_event) + dependencies = Set.new + @prerequisites.each do |prerequisites_event_name, prerequisites_event_value| + if prerequisites_event_name == sdk_event + for prereq_event in prerequisites_event_value + dependencies.add(prereq_event) + end + end + end + + @suppressed_by.each do |suppressed_event_name, suppressed_event_value| + if suppressed_event_value.include?(sdk_event) + dependencies.add(suppressed_event_name) + end + end + + return dependencies + end + end +end \ No newline at end of file diff --git a/lib/splitclient-rb/engine/models/events_metadata.rb b/lib/splitclient-rb/engine/models/events_metadata.rb new file mode 100644 index 00000000..208c24b5 --- /dev/null +++ b/lib/splitclient-rb/engine/models/events_metadata.rb @@ -0,0 +1,10 @@ +module SplitIoClient::Engine::Models + class EventsMetadata + attr_accessor :type, :names + + def initialize(type, names=nil) + @type = type + @names = names + end + end +end diff --git a/lib/splitclient-rb/engine/models/sdk_event.rb b/lib/splitclient-rb/engine/models/sdk_event.rb new file mode 100644 index 00000000..4d9fa189 --- /dev/null +++ b/lib/splitclient-rb/engine/models/sdk_event.rb @@ -0,0 +1,4 @@ +class SplitIoClient::Engine::Models::SdkEvent + SDK_READY = 'SDK_READY' + SDK_UPDATE = 'SDK_UPDATE' +end diff --git a/lib/splitclient-rb/engine/models/sdk_event_type.rb b/lib/splitclient-rb/engine/models/sdk_event_type.rb new file mode 100644 index 00000000..a8a8e0fc --- /dev/null +++ b/lib/splitclient-rb/engine/models/sdk_event_type.rb @@ -0,0 +1,4 @@ +class SplitIoClient::Engine::Models::SdkEventType + FLAG_UPDATE = 'FLAG_UPDATE' + SEGMENTS_UPDATE = 'SEGMENTS_UPDATE' +end diff --git a/lib/splitclient-rb/engine/models/sdk_internal_event.rb b/lib/splitclient-rb/engine/models/sdk_internal_event.rb new file mode 100644 index 00000000..8372a132 --- /dev/null +++ b/lib/splitclient-rb/engine/models/sdk_internal_event.rb @@ -0,0 +1,8 @@ +class SplitIoClient::Engine::Models::SdkInternalEvent + SDK_READY = 'SDK_READY' + FLAGS_UPDATED = 'FLAGS_UPDATED' + FLAG_KILLED_NOTIFICATION = 'FLAG_KILLED_NOTIFICATION' + SEGMENTS_UPDATED = 'SEGMENTS_UPDATED' + RB_SEGMENTS_UPDATED = 'RB_SEGMENTS_UPDATED' + LARGE_SEGMENTS_UPDATED = 'LARGE_SEGMENTS_UPDATED' +end diff --git a/spec/engine/events/events_manager_config_spec.rb b/spec/engine/events/events_manager_config_spec.rb new file mode 100644 index 00000000..46c0a5c3 --- /dev/null +++ b/spec/engine/events/events_manager_config_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe SplitIoClient::Engine::Events::EventsManagerConfig do + subject { SplitIoClient::Engine::Events::EventsManagerConfig } + + it 'test_build_instance' do + config = subject.new + + expect(config.require_all[SplitIoClient::Engine::Models::SdkEvent::SDK_READY].length).to eq(1) + expect(config.require_all[SplitIoClient::Engine::Models::SdkEvent::SDK_READY].include?(SplitIoClient::Engine::Models::SdkInternalEvent::SDK_READY)).to eq(true) + + expect(config.prerequisites[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].include?(SplitIoClient::Engine::Models::SdkEvent::SDK_READY)).to eq(true) + + expect(config.execution_limits[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE]).to eq(-1) + expect(config.execution_limits[SplitIoClient::Engine::Models::SdkEvent::SDK_READY]).to eq(1) + + expect(config.require_any[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].length).to eq(4) + expect(config.require_any[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].include?(SplitIoClient::Engine::Models::SdkInternalEvent::FLAG_KILLED_NOTIFICATION)).to be(true) + expect(config.require_any[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].include?(SplitIoClient::Engine::Models::SdkInternalEvent::FLAGS_UPDATED)).to be(true) + expect(config.require_any[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].include?(SplitIoClient::Engine::Models::SdkInternalEvent::RB_SEGMENTS_UPDATED)).to be(true) + expect(config.require_any[SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE].include?(SplitIoClient::Engine::Models::SdkInternalEvent::SEGMENTS_UPDATED)).to be(true) + + order = 0 + expect(config.evaluation_order.length).to eq(2) + config.evaluation_order.each do |sdk_event| + order += 1 + if order == 1 + expect(sdk_event).to eq(SplitIoClient::Engine::Models::SdkEvent::SDK_READY) + end + if order == 2 + expect(sdk_event).to eq(SplitIoClient::Engine::Models::SdkEvent::SDK_UPDATE) + end + end + end +end