Skip to content

Commit e7777fd

Browse files
Merge pull request #27 from dhruvCW/config_refactor
Refactor ABSmartly configuration setup to allow for all the configuration to be specified through the ABSmartlyConfig object
2 parents dea8e3e + 3f946e1 commit e7777fd

18 files changed

+180
-198
lines changed

.github/workflows/main.yml

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,16 @@ on: [push]
33
jobs:
44
build:
55
runs-on: ubuntu-latest
6+
strategy:
7+
matrix:
8+
ruby-version: [ '3.0', '3.1', '3.2', '3.3', '3.4' ]
69
steps:
710
- uses: actions/checkout@v3
811

912
- uses: ruby/setup-ruby@v1
1013
with:
11-
ruby-version: 3.0.0
14+
ruby-version: ${{ matrix.ruby-version }}
1215
bundler-cache: true
1316

14-
- name: Bundle install
15-
run: |
16-
gem install bundler
17-
bundle install --jobs 4 --retry 3
18-
1917
- name: Run RSpec
2018
run: COVERAGE=true bundle exec rspec

.ruby-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.7.6
1+
3.0.6

Gemfile.lock

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ GEM
3232
reline (0.1.5)
3333
io-console (~> 0.5)
3434
rexml (3.2.8)
35-
strscan (>= 3.0.9)
3635
rspec (3.11.0)
3736
rspec-core (~> 3.11.0)
3837
rspec-expectations (~> 3.11.0)
@@ -60,7 +59,6 @@ GEM
6059
parser (>= 3.1.1.0)
6160
ruby-progressbar (1.11.0)
6261
ruby2_keywords (0.0.5)
63-
strscan (3.1.0)
6462
unicode-display_width (2.2.0)
6563

6664
PLATFORMS

example/example.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,4 +82,4 @@
8282
}
8383
ctx2.track("payment", properties)
8484

85-
ctx2.close
85+
ctx2.close

lib/a_b_smartly.rb

Lines changed: 23 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,92 +1,51 @@
11
# frozen_string_literal: true
22

33
require "time"
4+
require "singleton"
5+
require "forwardable"
46
require_relative "context"
57
require_relative "audience_matcher"
6-
require_relative "default_context_data_provider"
7-
require_relative "default_context_event_handler"
8-
require_relative "default_variable_parser"
9-
require_relative "default_audience_deserializer"
10-
require_relative "scheduled_thread_pool_executor"
8+
require_relative "a_b_smartly_config"
9+
require_relative "absmartly/version"
1110

1211
class ABSmartly
13-
attr_accessor :context_data_provider, :context_event_handler,
14-
:variable_parser, :scheduler, :context_event_logger,
15-
:audience_deserializer, :client
12+
extend Forwardable
1613

17-
def self.configure_client(&block)
18-
@@init_http = block
19-
end
14+
attr_reader :config
15+
16+
def_delegators :@config, :context_data_provider, :context_event_handler, :variable_parser, :context_event_logger,
17+
:audience_deserializer, :client
18+
19+
def_delegators :@config, :endpoint, :api_key, :application, :environment
2020

2121
def self.create(config)
22-
ABSmartly.new(config)
22+
new(config)
2323
end
2424

2525
def initialize(config)
26-
@@init_http = nil
27-
@context_data_provider = config.context_data_provider
28-
@context_event_handler = config.context_event_handler
29-
@context_event_logger = config.context_event_logger
30-
@variable_parser = config.variable_parser
31-
@audience_deserializer = config.audience_deserializer
32-
@scheduler = config.scheduler
33-
34-
if @context_data_provider.nil? || @context_event_handler.nil?
35-
@client = config.client
36-
raise ArgumentError.new("Missing Client instance configuration") if @client.nil?
37-
38-
if @context_data_provider.nil?
39-
@context_data_provider = DefaultContextDataProvider.new(@client)
40-
end
41-
42-
if @context_event_handler.nil?
43-
@context_event_handler = DefaultContextEventHandler.new(@client)
44-
end
45-
end
26+
config.validate!
4627

47-
if @variable_parser.nil?
48-
@variable_parser = DefaultVariableParser.new
49-
end
50-
51-
if @audience_deserializer.nil?
52-
@audience_deserializer = DefaultAudienceDeserializer.new
53-
end
54-
if @scheduler.nil?
55-
@scheduler = ScheduledThreadPoolExecutor.new(1)
56-
end
28+
@config = config
5729
end
5830

59-
def create_context(config)
60-
validate_params(config)
61-
Context.create(get_utc_format, config, @context_data_provider.context_data,
62-
@context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
63-
AudienceMatcher.new(@audience_deserializer))
31+
def create_context(context_config)
32+
Context.create(get_utc_format, context_config, context_data,
33+
context_data_provider, context_event_handler, context_event_logger, variable_parser,
34+
AudienceMatcher.new(audience_deserializer))
6435
end
6536

66-
def create_context_with(config, data)
67-
Context.create(get_utc_format, config, data,
68-
@context_data_provider, @context_event_handler, @context_event_logger, @variable_parser,
69-
AudienceMatcher.new(@audience_deserializer))
37+
def create_context_with(context_config, data)
38+
Context.create(get_utc_format, context_config, data,
39+
context_data_provider, context_event_handler, context_event_logger, variable_parser,
40+
AudienceMatcher.new(audience_deserializer))
7041
end
7142

7243
def context_data
73-
@context_data_provider.context_data
44+
context_data_provider.context_data
7445
end
7546

7647
private
7748
def get_utc_format
7849
Time.now.utc.iso8601(3)
7950
end
80-
81-
def validate_params(params)
82-
params.units.each do |key, value|
83-
unless value.is_a?(String) || value.is_a?(Numeric)
84-
raise ArgumentError.new("Unit '#{key}' UID is of unsupported type '#{value.class}'. UID must be one of ['string', 'number']")
85-
end
86-
87-
if value.to_s.size.zero?
88-
raise ArgumentError.new("Unit '#{key}' UID length must be >= 1")
89-
end
90-
end
91-
end
9251
end

lib/a_b_smartly_config.rb

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,65 @@
11
# frozen_string_literal: true
22

3+
require "forwardable"
4+
5+
require_relative "client"
6+
require_relative "client_config"
7+
require_relative "default_context_data_provider"
8+
require_relative "default_context_event_handler"
9+
require_relative "default_variable_parser"
10+
require_relative "default_audience_deserializer"
11+
312
class ABSmartlyConfig
4-
attr_accessor :context_data_provider, :context_event_handler,
5-
:variable_parser, :scheduler, :context_event_logger,
6-
:client, :audience_deserializer
13+
extend Forwardable
14+
15+
attr_accessor :scheduler
16+
17+
attr_writer :context_data_provider, :context_event_handler, :audience_deserializer, :variable_parser, :client
18+
19+
attr_reader :client_config, :context_event_logger
20+
21+
def_delegators :@client_config, :endpoint, :api_key, :application, :environment
22+
def_delegators :@client_config, :connect_timeout, :connection_request_timeout, :retry_interval, :max_retries
23+
724
def self.create
8-
ABSmartlyConfig.new
25+
new
926
end
1027

11-
def context_data_provider=(context_data_provider)
12-
@context_data_provider = context_data_provider
13-
self
28+
def initialize
29+
@client_config = ClientConfig.new
1430
end
1531

16-
def context_event_handler=(context_event_handler)
17-
@context_event_handler = context_event_handler
18-
self
32+
def validate!
33+
raise ArgumentError.new("event logger not configured") if context_event_logger.nil?
34+
raise ArgumentError.new("failed to initialize client") if client.nil?
35+
raise ArgumentError.new("failed to initialize context_data_provider") if context_data_provider.nil?
1936
end
2037

21-
def context_data_provide
22-
@context_event_handler
38+
def context_event_logger=(context_event_logger)
39+
if context_event_logger.is_a?(Proc)
40+
@context_event_logger = ContextEventLoggerCallback.new(context_event_logger)
41+
else
42+
@context_event_logger = context_event_logger
43+
end
2344
end
2445

25-
def variable_parser=(variable_parser)
26-
@variable_parser = variable_parser
27-
self
46+
def variable_parser
47+
@variable_parser ||= DefaultVariableParser.new
2848
end
2949

30-
def scheduler=(scheduler)
31-
@scheduler = scheduler
32-
self
50+
def audience_deserializer
51+
@audience_deserializer ||= DefaultAudienceDeserializer.new
3352
end
3453

35-
def context_event_logger=(context_event_logger)
36-
@context_event_logger = context_event_logger
37-
self
54+
def context_data_provider
55+
@context_data_provider ||= DefaultContextDataProvider.new(client)
3856
end
3957

40-
def audience_deserializer=(audience_deserializer)
41-
@audience_deserializer = audience_deserializer
42-
self
58+
def context_event_handler
59+
@context_event_handler ||= DefaultContextEventHandler.new(client)
4360
end
4461

45-
def client=(client)
46-
@client = client
47-
self
62+
def client
63+
@client ||= Client.new(client_config)
4864
end
4965
end

lib/absmartly.rb

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@
88
require_relative "context_config"
99

1010
module Absmartly
11-
@@init_config = nil
12-
1311
class Error < StandardError
1412
end
1513

1614
class << self
17-
attr_accessor :endpoint, :api_key, :application, :environment
15+
MUTEX = Thread::Mutex.new
1816

1917
def configure_client
20-
yield self
18+
yield sdk_config
19+
20+
sdk_config.validate!
2121
end
2222

2323
def create
@@ -40,24 +40,15 @@ def context_data
4040
sdk.context_data
4141
end
4242

43-
private
44-
def client_config
45-
@client_config = ClientConfig.create
46-
@client_config.endpoint = @endpoint
47-
@client_config.api_key = @api_key
48-
@client_config.application = @application
49-
@client_config.environment = @environment
50-
@client_config
51-
end
43+
private_constant :MUTEX
5244

45+
private
5346
def sdk_config
54-
@sdk_config = ABSmartlyConfig.create
55-
@sdk_config.client = Client.create(client_config)
56-
@sdk_config
47+
MUTEX.synchronize { @sdk_config ||= ABSmartlyConfig.create }
5748
end
5849

5950
def sdk
60-
@sdk ||= create
51+
MUTEX.synchronize { @sdk ||= create }
6152
end
6253
end
6354
end

lib/absmartly/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# frozen_string_literal: true
22

33
module Absmartly
4-
VERSION = "1.1.2"
4+
VERSION = "1.2.0"
55
end

0 commit comments

Comments
 (0)