optimizely-sdk 3.4.0 → 3.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/optimizely.rb +383 -49
- data/lib/optimizely/audience.rb +31 -43
- data/lib/optimizely/bucketer.rb +36 -33
- data/lib/optimizely/config/datafile_project_config.rb +19 -3
- data/lib/optimizely/config/proxy_config.rb +34 -0
- data/lib/optimizely/config_manager/async_scheduler.rb +6 -2
- data/lib/optimizely/config_manager/http_project_config_manager.rb +40 -23
- data/lib/optimizely/custom_attribute_condition_evaluator.rb +133 -37
- data/lib/optimizely/decide/optimizely_decide_option.rb +28 -0
- data/lib/optimizely/decide/optimizely_decision.rb +60 -0
- data/lib/optimizely/decide/optimizely_decision_message.rb +26 -0
- data/lib/optimizely/decision_service.rb +163 -139
- data/lib/optimizely/event/entity/decision.rb +6 -4
- data/lib/optimizely/event/entity/impression_event.rb +4 -2
- data/lib/optimizely/event/event_factory.rb +4 -3
- data/lib/optimizely/event/user_event_factory.rb +4 -3
- data/lib/optimizely/event_dispatcher.rb +8 -14
- data/lib/optimizely/exceptions.rb +17 -9
- data/lib/optimizely/helpers/constants.rb +19 -5
- data/lib/optimizely/helpers/http_utils.rb +64 -0
- data/lib/optimizely/helpers/variable_type.rb +8 -1
- data/lib/optimizely/optimizely_config.rb +2 -1
- data/lib/optimizely/optimizely_factory.rb +54 -5
- data/lib/optimizely/optimizely_user_context.rb +107 -0
- data/lib/optimizely/project_config.rb +5 -1
- data/lib/optimizely/semantic_version.rb +166 -0
- data/lib/optimizely/version.rb +1 -1
- metadata +9 -16
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -17,19 +17,21 @@
|
|
17
17
|
#
|
18
18
|
module Optimizely
|
19
19
|
class Decision
|
20
|
-
attr_reader :campaign_id, :experiment_id, :variation_id
|
20
|
+
attr_reader :campaign_id, :experiment_id, :variation_id, :metadata
|
21
21
|
|
22
|
-
def initialize(campaign_id:, experiment_id:, variation_id:)
|
22
|
+
def initialize(campaign_id:, experiment_id:, variation_id:, metadata:)
|
23
23
|
@campaign_id = campaign_id
|
24
24
|
@experiment_id = experiment_id
|
25
25
|
@variation_id = variation_id
|
26
|
+
@metadata = metadata
|
26
27
|
end
|
27
28
|
|
28
29
|
def as_json
|
29
30
|
{
|
30
31
|
campaign_id: @campaign_id,
|
31
32
|
experiment_id: @experiment_id,
|
32
|
-
variation_id: @variation_id
|
33
|
+
variation_id: @variation_id,
|
34
|
+
metadata: @metadata
|
33
35
|
}
|
34
36
|
end
|
35
37
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -19,7 +19,7 @@ require_relative 'user_event'
|
|
19
19
|
require 'optimizely/helpers/date_time_utils'
|
20
20
|
module Optimizely
|
21
21
|
class ImpressionEvent < UserEvent
|
22
|
-
attr_reader :user_id, :experiment_layer_id, :experiment_id, :variation_id,
|
22
|
+
attr_reader :user_id, :experiment_layer_id, :experiment_id, :variation_id, :metadata,
|
23
23
|
:visitor_attributes, :bot_filtering
|
24
24
|
|
25
25
|
def initialize(
|
@@ -28,6 +28,7 @@ module Optimizely
|
|
28
28
|
experiment_layer_id:,
|
29
29
|
experiment_id:,
|
30
30
|
variation_id:,
|
31
|
+
metadata:,
|
31
32
|
visitor_attributes:,
|
32
33
|
bot_filtering:
|
33
34
|
)
|
@@ -38,6 +39,7 @@ module Optimizely
|
|
38
39
|
@experiment_layer_id = experiment_layer_id
|
39
40
|
@experiment_id = experiment_id
|
40
41
|
@variation_id = variation_id
|
42
|
+
@metadata = metadata
|
41
43
|
@visitor_attributes = visitor_attributes
|
42
44
|
@bot_filtering = bot_filtering
|
43
45
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -101,10 +101,11 @@ module Optimizely
|
|
101
101
|
private
|
102
102
|
|
103
103
|
def create_impression_event_visitor(impression_event)
|
104
|
-
decision =
|
104
|
+
decision = Decision.new(
|
105
105
|
campaign_id: impression_event.experiment_layer_id,
|
106
106
|
experiment_id: impression_event.experiment_id,
|
107
|
-
variation_id: impression_event.variation_id
|
107
|
+
variation_id: impression_event.variation_id,
|
108
|
+
metadata: impression_event.metadata
|
108
109
|
)
|
109
110
|
|
110
111
|
snapshot_event = Optimizely::SnapshotEvent.new(
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2019, Optimizely and contributors
|
4
|
+
# Copyright 2019-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -22,7 +22,7 @@ require_relative 'event_factory'
|
|
22
22
|
module Optimizely
|
23
23
|
class UserEventFactory
|
24
24
|
# UserEventFactory builds ImpressionEvent and ConversionEvent objects from a given user_event.
|
25
|
-
def self.create_impression_event(project_config, experiment, variation_id, user_id, user_attributes)
|
25
|
+
def self.create_impression_event(project_config, experiment, variation_id, metadata, user_id, user_attributes)
|
26
26
|
# Create impression Event to be sent to the logging endpoint.
|
27
27
|
#
|
28
28
|
# project_config - Instance of ProjectConfig
|
@@ -42,13 +42,14 @@ module Optimizely
|
|
42
42
|
).as_json
|
43
43
|
|
44
44
|
visitor_attributes = Optimizely::EventFactory.build_attribute_list(user_attributes, project_config)
|
45
|
-
experiment_layer_id =
|
45
|
+
experiment_layer_id = experiment['layerId']
|
46
46
|
Optimizely::ImpressionEvent.new(
|
47
47
|
event_context: event_context,
|
48
48
|
user_id: user_id,
|
49
49
|
experiment_layer_id: experiment_layer_id,
|
50
50
|
experiment_id: experiment['id'],
|
51
51
|
variation_id: variation_id,
|
52
|
+
metadata: metadata,
|
52
53
|
visitor_attributes: visitor_attributes,
|
53
54
|
bot_filtering: project_config.bot_filtering
|
54
55
|
)
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-2017, 2019
|
4
|
+
# Copyright 2016-2017, 2019-2020 Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -16,8 +16,7 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
require_relative 'exceptions'
|
19
|
-
|
20
|
-
require 'httparty'
|
19
|
+
require_relative 'helpers/http_utils'
|
21
20
|
|
22
21
|
module Optimizely
|
23
22
|
class NoOpEventDispatcher
|
@@ -30,28 +29,23 @@ module Optimizely
|
|
30
29
|
# @api constants
|
31
30
|
REQUEST_TIMEOUT = 10
|
32
31
|
|
33
|
-
def initialize(logger: nil, error_handler: nil)
|
32
|
+
def initialize(logger: nil, error_handler: nil, proxy_config: nil)
|
34
33
|
@logger = logger || NoOpLogger.new
|
35
34
|
@error_handler = error_handler || NoOpErrorHandler.new
|
35
|
+
@proxy_config = proxy_config
|
36
36
|
end
|
37
37
|
|
38
38
|
# Dispatch the event being represented by the Event object.
|
39
39
|
#
|
40
40
|
# @param event - Event object
|
41
41
|
def dispatch_event(event)
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
elsif event.http_verb == :post
|
46
|
-
response = HTTParty.post(event.url,
|
47
|
-
body: event.params.to_json,
|
48
|
-
headers: event.headers,
|
49
|
-
timeout: REQUEST_TIMEOUT)
|
50
|
-
end
|
42
|
+
response = Helpers::HttpUtils.make_request(
|
43
|
+
event.url, event.http_verb, event.params.to_json, event.headers, REQUEST_TIMEOUT, @proxy_config
|
44
|
+
)
|
51
45
|
|
52
46
|
error_msg = "Event failed to dispatch with response code: #{response.code}"
|
53
47
|
|
54
|
-
case response.code
|
48
|
+
case response.code.to_i
|
55
49
|
when 400...500
|
56
50
|
@logger.log(Logger::ERROR, error_msg)
|
57
51
|
@error_handler.handle_error(HTTPCallError.new("HTTP Client Error: #{response.code}"))
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-
|
4
|
+
# Copyright 2016-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -81,14 +81,6 @@ module Optimizely
|
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
|
-
class InvalidDatafileError < Error
|
85
|
-
# Raised when a public method fails due to an invalid datafile
|
86
|
-
|
87
|
-
def initialize(aborted_method)
|
88
|
-
super("Provided datafile is in an invalid format. Aborting #{aborted_method}.")
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
84
|
class InvalidDatafileVersionError < Error
|
93
85
|
# Raised when a datafile with an unsupported version is provided
|
94
86
|
|
@@ -128,4 +120,20 @@ module Optimizely
|
|
128
120
|
super("Optimizely instance is not valid. Failing '#{aborted_method}'.")
|
129
121
|
end
|
130
122
|
end
|
123
|
+
|
124
|
+
class InvalidAttributeType < Error
|
125
|
+
# Raised when an attribute is not provided in expected type.
|
126
|
+
|
127
|
+
def initialize(msg = 'Provided attribute value is not in the expected data type.')
|
128
|
+
super
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
class InvalidSemanticVersion < Error
|
133
|
+
# Raised when an invalid value is provided as semantic version.
|
134
|
+
|
135
|
+
def initialize(msg = 'Provided semantic version is invalid.')
|
136
|
+
super
|
137
|
+
end
|
138
|
+
end
|
131
139
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2016-
|
4
|
+
# Copyright 2016-2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -304,7 +304,8 @@ module Optimizely
|
|
304
304
|
'BOOLEAN' => 'boolean',
|
305
305
|
'DOUBLE' => 'double',
|
306
306
|
'INTEGER' => 'integer',
|
307
|
-
'STRING' => 'string'
|
307
|
+
'STRING' => 'string',
|
308
|
+
'JSON' => 'json'
|
308
309
|
}.freeze
|
309
310
|
|
310
311
|
INPUT_VARIABLES = {
|
@@ -334,11 +335,11 @@ module Optimizely
|
|
334
335
|
|
335
336
|
AUDIENCE_EVALUATION_LOGS = {
|
336
337
|
'AUDIENCE_EVALUATION_RESULT' => "Audience '%s' evaluated to %s.",
|
337
|
-
'AUDIENCE_EVALUATION_RESULT_COMBINED' => "Audiences for experiment '%s' collectively evaluated to %s.",
|
338
338
|
'EVALUATING_AUDIENCE' => "Starting to evaluate audience '%s' with conditions: %s.",
|
339
|
-
'EVALUATING_AUDIENCES_COMBINED' => "Evaluating audiences for experiment '%s': %s.",
|
340
339
|
'INFINITE_ATTRIBUTE_VALUE' => 'Audience condition %s evaluated to UNKNOWN because the number value ' \
|
341
340
|
"for user attribute '%s' is not in the range [-2^53, +2^53].",
|
341
|
+
'INVALID_SEMANTIC_VERSION' => 'Audience condition %s evaluated as UNKNOWN because an invalid semantic version ' \
|
342
|
+
"was passed for user attribute '%s'.",
|
342
343
|
'MISSING_ATTRIBUTE_VALUE' => 'Audience condition %s evaluated as UNKNOWN because no value ' \
|
343
344
|
"was passed for user attribute '%s'.",
|
344
345
|
'NULL_ATTRIBUTE_VALUE' => 'Audience condition %s evaluated to UNKNOWN because a nil value was passed ' \
|
@@ -353,15 +354,28 @@ module Optimizely
|
|
353
354
|
'to upgrade to a newer release of the Optimizely SDK.'
|
354
355
|
}.freeze
|
355
356
|
|
357
|
+
EXPERIMENT_AUDIENCE_EVALUATION_LOGS = {
|
358
|
+
'AUDIENCE_EVALUATION_RESULT_COMBINED' => "Audiences for experiment '%s' collectively evaluated to %s.",
|
359
|
+
'EVALUATING_AUDIENCES_COMBINED' => "Evaluating audiences for experiment '%s': %s."
|
360
|
+
}.merge(AUDIENCE_EVALUATION_LOGS).freeze
|
361
|
+
|
362
|
+
ROLLOUT_AUDIENCE_EVALUATION_LOGS = {
|
363
|
+
'AUDIENCE_EVALUATION_RESULT_COMBINED' => "Audiences for rule '%s' collectively evaluated to %s.",
|
364
|
+
'EVALUATING_AUDIENCES_COMBINED' => "Evaluating audiences for rule '%s': %s."
|
365
|
+
}.merge(AUDIENCE_EVALUATION_LOGS).freeze
|
366
|
+
|
356
367
|
DECISION_NOTIFICATION_TYPES = {
|
357
368
|
'AB_TEST' => 'ab-test',
|
358
369
|
'FEATURE' => 'feature',
|
359
370
|
'FEATURE_TEST' => 'feature-test',
|
360
|
-
'FEATURE_VARIABLE' => 'feature-variable'
|
371
|
+
'FEATURE_VARIABLE' => 'feature-variable',
|
372
|
+
'FLAG' => 'flag',
|
373
|
+
'ALL_FEATURE_VARIABLES' => 'all-feature-variables'
|
361
374
|
}.freeze
|
362
375
|
|
363
376
|
CONFIG_MANAGER = {
|
364
377
|
'DATAFILE_URL_TEMPLATE' => 'https://cdn.optimizely.com/datafiles/%s.json',
|
378
|
+
'AUTHENTICATED_DATAFILE_URL_TEMPLATE' => 'https://config.optimizely.com/datafiles/auth/%s.json',
|
365
379
|
# Default time in seconds to block the 'config' method call until 'config' instance has been initialized.
|
366
380
|
'DEFAULT_BLOCKING_TIMEOUT' => 15,
|
367
381
|
# Default config update interval of 5 minutes
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright 2020, Optimizely and contributors
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'net/http'
|
20
|
+
|
21
|
+
module Optimizely
|
22
|
+
module Helpers
|
23
|
+
module HttpUtils
|
24
|
+
module_function
|
25
|
+
|
26
|
+
def make_request(url, http_method, request_body = nil, headers = {}, read_timeout = nil, proxy_config = nil)
|
27
|
+
# makes http/https GET/POST request and returns response
|
28
|
+
#
|
29
|
+
uri = URI.parse(url)
|
30
|
+
|
31
|
+
if http_method == :get
|
32
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
33
|
+
elsif http_method == :post
|
34
|
+
request = Net::HTTP::Post.new(uri.request_uri)
|
35
|
+
request.body = request_body if request_body
|
36
|
+
else
|
37
|
+
return nil
|
38
|
+
end
|
39
|
+
|
40
|
+
# set headers
|
41
|
+
headers&.each do |key, val|
|
42
|
+
request[key] = val
|
43
|
+
end
|
44
|
+
|
45
|
+
# do not try to make request with proxy unless we have at least a host
|
46
|
+
http_class = if proxy_config&.host
|
47
|
+
Net::HTTP::Proxy(
|
48
|
+
proxy_config.host,
|
49
|
+
proxy_config.port,
|
50
|
+
proxy_config.username,
|
51
|
+
proxy_config.password
|
52
|
+
)
|
53
|
+
else
|
54
|
+
Net::HTTP
|
55
|
+
end
|
56
|
+
|
57
|
+
http = http_class.new(uri.host, uri.port)
|
58
|
+
http.read_timeout = read_timeout if read_timeout
|
59
|
+
http.use_ssl = uri.scheme == 'https'
|
60
|
+
http.request(request)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
#
|
4
|
-
# Copyright 2017, Optimizely and contributors
|
4
|
+
# Copyright 2017, 2020, Optimizely and contributors
|
5
5
|
#
|
6
6
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
7
|
# you may not use this file except in compliance with the License.
|
@@ -48,6 +48,13 @@ module Optimizely
|
|
48
48
|
logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type "\
|
49
49
|
"'#{variable_type}': #{e.message}.")
|
50
50
|
end
|
51
|
+
when 'json'
|
52
|
+
begin
|
53
|
+
return_value = JSON.parse(value)
|
54
|
+
rescue => e
|
55
|
+
logger.log(Logger::ERROR, "Unable to cast variable value '#{value}' to type "\
|
56
|
+
"'#{variable_type}': #{e.message}.")
|
57
|
+
end
|
51
58
|
else
|
52
59
|
# default case is string
|
53
60
|
return_value = value
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright 2019, Optimizely and contributors
|
3
|
+
# Copyright 2019-2020, Optimizely and contributors
|
4
4
|
#
|
5
5
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
6
6
|
# you may not use this file except in compliance with the License.
|
@@ -25,6 +25,7 @@ module Optimizely
|
|
25
25
|
experiments_map_object = experiments_map
|
26
26
|
features_map = get_features_map(experiments_map_object)
|
27
27
|
{
|
28
|
+
'datafile' => @project_config.datafile,
|
28
29
|
'experimentsMap' => experiments_map_object,
|
29
30
|
'featuresMap' => features_map,
|
30
31
|
'revision' => @project_config.revision
|
@@ -17,16 +17,18 @@
|
|
17
17
|
#
|
18
18
|
|
19
19
|
require 'optimizely'
|
20
|
+
require 'optimizely/error_handler'
|
20
21
|
require 'optimizely/event_dispatcher'
|
21
22
|
require 'optimizely/event/batch_event_processor'
|
23
|
+
require 'optimizely/logger'
|
24
|
+
require 'optimizely/notification_center'
|
25
|
+
|
22
26
|
module Optimizely
|
23
27
|
class OptimizelyFactory
|
24
|
-
attr_reader :max_event_batch_size, :max_event_flush_interval
|
25
|
-
|
26
28
|
# Convenience method for setting the maximum number of events contained within a batch.
|
27
29
|
# @param batch_size Integer - Sets size of EventQueue.
|
28
30
|
# @param logger - Optional LoggerInterface Provides a log method to log messages.
|
29
|
-
def self.max_event_batch_size(batch_size, logger)
|
31
|
+
def self.max_event_batch_size(batch_size, logger = NoOpLogger.new)
|
30
32
|
unless batch_size.is_a? Integer
|
31
33
|
logger.log(
|
32
34
|
Logger::ERROR,
|
@@ -48,7 +50,7 @@ module Optimizely
|
|
48
50
|
# Convenience method for setting the maximum time interval in milliseconds between event dispatches.
|
49
51
|
# @param flush_interval Numeric - Time interval between event dispatches.
|
50
52
|
# @param logger - Optional LoggerInterface Provides a log method to log messages.
|
51
|
-
def self.max_event_flush_interval(flush_interval, logger)
|
53
|
+
def self.max_event_flush_interval(flush_interval, logger = NoOpLogger.new)
|
52
54
|
unless flush_interval.is_a? Numeric
|
53
55
|
logger.log(
|
54
56
|
Logger::ERROR,
|
@@ -67,12 +69,42 @@ module Optimizely
|
|
67
69
|
@max_event_flush_interval = flush_interval
|
68
70
|
end
|
69
71
|
|
72
|
+
# Convenience method for setting frequency at which datafile has to be polled and ProjectConfig updated.
|
73
|
+
#
|
74
|
+
# @param polling_interval Numeric - Time in seconds after which to update datafile.
|
75
|
+
def self.polling_interval(polling_interval)
|
76
|
+
@polling_interval = polling_interval
|
77
|
+
end
|
78
|
+
|
79
|
+
# Convenience method for setting timeout to block the config call until config has been initialized.
|
80
|
+
#
|
81
|
+
# @param blocking_timeout Numeric - Time in seconds.
|
82
|
+
def self.blocking_timeout(blocking_timeout)
|
83
|
+
@blocking_timeout = blocking_timeout
|
84
|
+
end
|
85
|
+
|
70
86
|
# Returns a new optimizely instance.
|
71
87
|
#
|
72
88
|
# @params sdk_key - Required String uniquely identifying the fallback datafile corresponding to project.
|
73
89
|
# @param fallback datafile - Optional JSON string datafile.
|
74
90
|
def self.default_instance(sdk_key, datafile = nil)
|
75
|
-
|
91
|
+
error_handler = NoOpErrorHandler.new
|
92
|
+
logger = NoOpLogger.new
|
93
|
+
notification_center = NotificationCenter.new(logger, error_handler)
|
94
|
+
|
95
|
+
config_manager = Optimizely::HTTPProjectConfigManager.new(
|
96
|
+
sdk_key: sdk_key,
|
97
|
+
polling_interval: @polling_interval,
|
98
|
+
blocking_timeout: @blocking_timeout,
|
99
|
+
datafile: datafile,
|
100
|
+
logger: logger,
|
101
|
+
error_handler: error_handler,
|
102
|
+
notification_center: notification_center
|
103
|
+
)
|
104
|
+
|
105
|
+
Optimizely::Project.new(
|
106
|
+
datafile, nil, logger, error_handler, nil, nil, sdk_key, config_manager, notification_center
|
107
|
+
)
|
76
108
|
end
|
77
109
|
|
78
110
|
# Returns a new optimizely instance.
|
@@ -108,10 +140,27 @@ module Optimizely
|
|
108
140
|
config_manager = nil,
|
109
141
|
notification_center = nil
|
110
142
|
)
|
143
|
+
|
144
|
+
error_handler ||= NoOpErrorHandler.new
|
145
|
+
logger ||= NoOpLogger.new
|
146
|
+
notification_center = notification_center.is_a?(Optimizely::NotificationCenter) ? notification_center : NotificationCenter.new(logger, error_handler)
|
147
|
+
|
111
148
|
event_processor = BatchEventProcessor.new(
|
112
149
|
event_dispatcher: event_dispatcher || EventDispatcher.new,
|
113
150
|
batch_size: @max_event_batch_size,
|
114
151
|
flush_interval: @max_event_flush_interval,
|
152
|
+
logger: logger,
|
153
|
+
notification_center: notification_center
|
154
|
+
)
|
155
|
+
|
156
|
+
config_manager ||= Optimizely::HTTPProjectConfigManager.new(
|
157
|
+
sdk_key: sdk_key,
|
158
|
+
polling_interval: @polling_interval,
|
159
|
+
blocking_timeout: @blocking_timeout,
|
160
|
+
datafile: datafile,
|
161
|
+
logger: logger,
|
162
|
+
error_handler: error_handler,
|
163
|
+
skip_json_validation: skip_json_validation,
|
115
164
|
notification_center: notification_center
|
116
165
|
)
|
117
166
|
|