vwo-sdk 1.5.0 → 1.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/vwo/constants.rb +26 -3
- data/lib/vwo/core/bucketer.rb +4 -6
- data/lib/vwo/core/variation_decider.rb +337 -45
- data/lib/vwo/enums.rb +49 -9
- data/lib/vwo/logger.rb +1 -1
- data/lib/vwo/schemas/settings_file.rb +1 -1
- data/lib/vwo/services/batch_events_dispatcher.rb +110 -0
- data/lib/vwo/services/batch_events_queue.rb +175 -0
- data/lib/vwo/services/event_dispatcher.rb +1 -13
- data/lib/vwo/services/hooks_manager.rb +36 -0
- data/lib/vwo/services/operand_evaluator.rb +10 -2
- data/lib/vwo/services/segment_evaluator.rb +5 -26
- data/lib/vwo/services/settings_file_manager.rb +8 -4
- data/lib/vwo/services/settings_file_processor.rb +6 -1
- data/lib/vwo/services/usage_stats.rb +29 -0
- data/lib/vwo/user_storage.rb +1 -1
- data/lib/vwo/utils/campaign.rb +108 -1
- data/lib/vwo/utils/custom_dimensions.rb +26 -3
- data/lib/vwo/utils/feature.rb +1 -1
- data/lib/vwo/utils/function.rb +1 -1
- data/lib/vwo/utils/impression.rb +58 -7
- data/lib/vwo/utils/request.rb +15 -1
- data/lib/vwo/utils/segment.rb +1 -1
- data/lib/vwo/utils/uuid.rb +1 -1
- data/lib/vwo/utils/validations.rb +85 -1
- data/lib/vwo.rb +586 -203
- metadata +36 -13
data/lib/vwo/enums.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019-
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -42,6 +42,7 @@ class VWO
|
|
42
42
|
|
43
43
|
module OperandTypes
|
44
44
|
CUSTOM_VARIABLE = 'custom_variable'
|
45
|
+
USER = 'user'
|
45
46
|
end
|
46
47
|
|
47
48
|
module OperandValuesBooleanTypes
|
@@ -49,6 +50,16 @@ class VWO
|
|
49
50
|
FALSE = 'false'
|
50
51
|
end
|
51
52
|
|
53
|
+
module StatusEnum
|
54
|
+
PASSED = 'passed'
|
55
|
+
FAILED = 'failed'
|
56
|
+
end
|
57
|
+
|
58
|
+
module SegmentationTypeEnum
|
59
|
+
WHITELISTING = 'whitelisting'
|
60
|
+
PRE_SEGMENTATION = 'pre-segmentation'
|
61
|
+
end
|
62
|
+
|
52
63
|
module FileNameEnum
|
53
64
|
VWO_PATH = 'vwo'
|
54
65
|
UTIL_PATH = 'vwo/utils'
|
@@ -60,6 +71,8 @@ class VWO
|
|
60
71
|
SegmentEvaluator = VWO_PATH + '/services/segment_evaluator'
|
61
72
|
Logger = VWO_PATH + '/logger'
|
62
73
|
SettingsFileProcessor = VWO_PATH + '/services/settings_file_processor'
|
74
|
+
BatchEventsQueue = VWO_PATH + '/services/batch_events_queue'
|
75
|
+
BatchEventsDispatcher = VWO_PATH + '/services/batch_events_dispatcher'
|
63
76
|
|
64
77
|
CampaignUtil = UTIL_PATH + '/campaign'
|
65
78
|
FunctionUtil = UTIL_PATH + '/function'
|
@@ -93,7 +106,13 @@ class VWO
|
|
93
106
|
IMPRESSION_FOR_TRACK_USER = '(%<file>s): Impression built for track-user - %<properties>s'
|
94
107
|
IMPRESSION_FOR_TRACK_GOAL = '(%<file>s): Impression built for track-goal - %<properties>s'
|
95
108
|
GOT_VARIATION_FOR_USER = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s got variationName:%<variation_name>s'
|
109
|
+
SEGMENTATION_STATUS = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s of campaign:%<campaign_key>s with variables:%<custom_variables>s %<status>s %<segmentation_type>s for %<variation_name>s'
|
96
110
|
PARAMS_FOR_PUSH_CALL = '(%<file>s): Params for push call - %<properties>s'
|
111
|
+
CAMPAIGN_NOT_ACTIVATED = '(%<file>s): Campaign:%<campaign_key>s for User ID:%<user_id>s is not yet activated for API:%<api_name>s. Use activate API to activate A/B test or isFeatureEnabled API to activate Feature Test.'
|
112
|
+
BATCH_EVENT_LIMIT_EXCEEDED = '(%<file>s): Impression event - %<end_point>s failed due to exceeding payload size. Parameter eventsPerRequest in batchEvents config in launch API has value:%<eventsPerRequest>s for accountId:%<accountId>s. Please read the official documentation for knowing the size limits.'
|
113
|
+
BULK_NOT_PROCESSED = "(%<file>s): Batch events couldn't be received by VWO. Calling Flush Callback with error and data."
|
114
|
+
BEFORE_FLUSHING = '(%<file>s): Flushing events queue %<manually>s having %<length>s events %<timer>s queue summary: %<queue_metadata>s'
|
115
|
+
EVENT_BATCHING_INSUFFICIENT = '(%<file>s): %<key>s not provided, assigning default value'
|
97
116
|
end
|
98
117
|
|
99
118
|
# Info Messages
|
@@ -108,9 +127,9 @@ class VWO
|
|
108
127
|
AUDIENCE_CONDITION_NOT_MET = '(%<file>s): userId:%<user_id>s does not become part of campaign because of not meeting audience conditions'
|
109
128
|
GOT_VARIATION_FOR_USER = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s got variationName:%<variation_name>s'
|
110
129
|
USER_GOT_NO_VARIATION = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s did not allot any variation'
|
111
|
-
IMPRESSION_SUCCESS = '(%<file>s): Impression event - %<end_point>s was successfully received by VWO having main keys:
|
112
|
-
MAIN_KEYS_FOR_IMPRESSION = '(%<file>s): Having main keys:
|
113
|
-
MAIN_KEYS_FOR_PUSH_API = '(%<file>s): Having main keys:
|
130
|
+
IMPRESSION_SUCCESS = '(%<file>s): Impression event - %<end_point>s was successfully received by VWO having main keys: sdkKey:%<sdk_key>s accountId:%<account_id>s campaignId:%<campaign_id>s and variationId:%<variation_id>s'
|
131
|
+
MAIN_KEYS_FOR_IMPRESSION = '(%<file>s): Having main keys: {sdkKey:%<sdk_key>s accountId:%<account_id>s campaignId:%<campaign_id>s and variationId:%<variation_id>s}'
|
132
|
+
MAIN_KEYS_FOR_PUSH_API = '(%<file>s): Having main keys: {sdkKey:%<sdk_key>s accountId:%<account_id>s u:%<u>s and tags:%<tags>s}'
|
114
133
|
INVALID_VARIATION_KEY = '(%<file>s): Variation was not assigned to userId:%<user_id>s for campaign:%<campaign_key>s'
|
115
134
|
|
116
135
|
USER_IN_FEATURE_ROLLOUT = '(%<file>s): User ID:%<user_id>s is in feature rollout:%<campaign_key>s'
|
@@ -120,11 +139,22 @@ class VWO
|
|
120
139
|
|
121
140
|
VARIABLE_FOUND = '(%<file>s): In API: %<api_name>s Value for variable:%<variable_key>s of campaign:%<campaign_key>s and campaign type: %<campaign_type>s is:%<variable_value>s for user:%<user_id>s'
|
122
141
|
|
123
|
-
|
124
|
-
|
142
|
+
USER_PASSED_SEGMENTATION = '(%<file>s): UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s passed segmentation'
|
143
|
+
USER_FAILED_SEGMENTATION = '(%<file>s): UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s failed segmentation'
|
125
144
|
|
126
145
|
NO_CUSTOM_VARIABLES = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s preSegments/customVariables are not passed for campaign:%<campaign_key>s and campaign has pre-segmentation'
|
127
|
-
|
146
|
+
SKIPPING_SEGMENTATION = '(%<file>s): In API: %<api_name>s, Skipping segmentation:%<variation>s for UserId:%<user_id>s as no valid segments found in campaign:%<campaign_key>s'
|
147
|
+
|
148
|
+
SEGMENTATION_STATUS = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s of campaign:%<campaign_key>s with variables:%<custom_variables>s %<status>s %<segmentation_type>s %<variation_name>s'
|
149
|
+
WHITELISTING_SKIPPED = '(%<file>s): In API: %<api_name>s, Skipping whitelisting for UserId:%<user_id>s of campaign:%<campaign_key>s'
|
150
|
+
SETTINGS_NOT_UPDATED = '(%<file>s): Settings-file fetched are same as earlier fetched settings'
|
151
|
+
SETTINGS_FILE_UPDATED = '(%<file>s): %<api_name>s vwo_sdk_instance is updated with the latest settings_file'
|
152
|
+
CAMPAIGN_NOT_ACTIVATED = '(%<file>s): Activate the campaign:%<campaign_key>s for User ID:%<user_id>s to %<reason>s.'
|
153
|
+
GOAL_ALREADY_TRACKED = '(%<file>s): Goal:%<goal_identifier>s of Campaign:%<campaign_key>s for User ID:%<user_id>s has already been tracked earlier. Skipping now'
|
154
|
+
USER_ALREADY_TRACKED = '(%<file>s): User ID:%<user_id>s for Campaign:%<campaign_key>s has already been tracked earlier for "%<api_name>s" API. Skipping now'
|
155
|
+
API_CALLED = '(%<file>s): API: {api_name} called for UserId:%<user_id>s'
|
156
|
+
BULK_IMPRESSION_SUCCESS = '(%<file>s): Impression event - %<end_point>s was successfully received by VWO having accountId:%<a>s'
|
157
|
+
AFTER_FLUSHING = '(%<file>s): Events queue having %<length>s events has been flushed %<manually>s queue summary: %<queue_metadata>s'
|
128
158
|
end
|
129
159
|
|
130
160
|
# Warning Messages
|
@@ -137,7 +167,7 @@ class VWO
|
|
137
167
|
API_CONFIG_CORRUPTED = '(%<file>s): %<api_name>s API has corrupted configuration'
|
138
168
|
GET_VARIATION_NAME_API_INVALID_PARAMS = '(%<file>s): %<api_name>s API got bad parameters. It expects campaignTestKey(String) as first and userId(String) as second argument, customVariables(Hash) can be passed via options for pre-segmentation'
|
139
169
|
GET_VARIATION_API_CONFIG_CORRUPTED = '(%<file>s): "getVariation" API has corrupted configuration'
|
140
|
-
TRACK_API_INVALID_PARAMS = '(%<file>s): %<api_name>s API got bad parameters. It expects campaignTestKey(String) as first userId(String) as second and goalIdentifier(String/Number) as third argument. Fourth is revenueValue(Float/Number/String) and is required for revenue goal only. customVariables(Hash) can be passed via options for pre-segmentation'
|
170
|
+
TRACK_API_INVALID_PARAMS = '(%<file>s): %<api_name>s API got bad parameters. It expects campaignTestKey(Nil/String/Array) as first userId(String) as second and goalIdentifier(String/Number) as third argument. Fourth is revenueValue(Float/Number/String) and is required for revenue goal only. customVariables(Hash) can be passed via options for pre-segmentation'
|
141
171
|
TRACK_API_CONFIG_CORRUPTED = '(%<file>s): "track" API has corrupted configuration'
|
142
172
|
TRACK_API_GOAL_NOT_FOUND = '(%<file>s): Goal:%<goal_identifier>s not found for campaign:%<campaign_key>s and userId:%<user_id>s'
|
143
173
|
TRACK_API_REVENUE_NOT_PASSED_FOR_REVENUE_GOAL = '(%<file>s): Revenue value should be passed for revenue goal:%<goal_identifier>s for campaign:%<campaign_key>s and userId:%<user_id>s'
|
@@ -159,11 +189,21 @@ class VWO
|
|
159
189
|
USER_NOT_IN_CAMPAIGN = '(%<file>s): userId:%<user_id>s did not become part of campaign:%<campaign_key>s and campaign type:%<campaign_type>s'
|
160
190
|
API_NOT_WORKING = '(%<file>s): API: %<api_name>s not working, exception caught: %<exception>s. Please contact VWO Support for help.'
|
161
191
|
|
162
|
-
|
192
|
+
SEGMENTATION_ERROR = '(%<file>s): Error while segmenting the UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s. Error message: %<error_message>s'
|
163
193
|
|
164
194
|
PUSH_API_INVALID_PARAMS = '(%<file>s): %<api_name>s API got bad parameters. It expects tag_key(String) as first and tag_value(String) as second argument and user_id(String) as third argument'
|
165
195
|
TAG_VALUE_LENGTH_EXCEEDED = '(%<file>s): In API: %<api_name>s, the length of tag_value:%<tag_value>s and userID: %<user_id>s can not be greater than 255'
|
166
196
|
TAG_KEY_LENGTH_EXCEEDED = '(%<file>s): In API: %<api_name>s, the length of tag_key:%<tag_key>s and userID: %<user_id>s can not be greater than 255'
|
197
|
+
TRACK_API_MISSING_PARAMS = '(%<file>s): "track" API got bad parameters. It expects campaignKey(null/String/array) as first, userId(String/Number) as second and goalIdentifier (string) as third argument. options is revenueValue(Float/Number/String) and is required for revenue goal only.'
|
198
|
+
NO_CAMPAIGN_FOUND = '(%<file>s): No campaign found for goal_identifier:%<goal_identifier>s. Please verify from VWO app.'
|
199
|
+
INVALID_TRACK_RETURNING_USER_VALUE = '(%<file>s): should_track_returning_user should be boolean'
|
200
|
+
INVALID_GOAL_TYPE = '(%<file>s): goal_type_to_track should be certain strings'
|
201
|
+
EVENT_BATCHING_NOT_OBJECT = '(%<file>s): Batch events settings are not of type object.'
|
202
|
+
EVENTS_PER_REQUEST_INVALID = '(%<file>s): events_per_request should be an integer'
|
203
|
+
REQUEST_TIME_INTERVAL_INVALID = '(%<file>s): request_time_interval should be a number'
|
204
|
+
EVENTS_PER_REQUEST_OUT_OF_BOUNDS = '(%<file>s): events_per_request should be >= %<min_value>s and <= %<max_value>s'
|
205
|
+
REQUEST_TIME_INTERVAL_OUT_OF_BOUNDS = '(%<file>s): request_time_interval should be >= %<min_value>s'
|
206
|
+
FLUSH_CALLBACK_INVALID = '(%<file>s): flush_callback is not callable'
|
167
207
|
end
|
168
208
|
end
|
169
209
|
|
data/lib/vwo/logger.rb
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative '../logger'
|
16
|
+
require_relative '../enums'
|
17
|
+
require_relative '../utils/request'
|
18
|
+
class VWO
|
19
|
+
module Services
|
20
|
+
class BatchEventsDispatcher
|
21
|
+
include VWO::Enums
|
22
|
+
# Initialize the BatchEventDispatcher with logger and development mode
|
23
|
+
#
|
24
|
+
# @param [Boolean] : To specify whether the request
|
25
|
+
# to our server should be made or not.
|
26
|
+
#
|
27
|
+
def initialize
|
28
|
+
@logger = VWO::Logger.get_instance
|
29
|
+
@queue = []
|
30
|
+
end
|
31
|
+
|
32
|
+
# Dispatch the impression event having properties object only if dev-mode is OFF
|
33
|
+
#
|
34
|
+
# @param[Hash] :properties hash having impression properties
|
35
|
+
# the request to be dispatched to the VWO server
|
36
|
+
# @return[Boolean]
|
37
|
+
#
|
38
|
+
def dispatch(impression, callback, query_params)
|
39
|
+
url = CONSTANTS::HTTPS_PROTOCOL + CONSTANTS::ENDPOINTS::BASE_URL + CONSTANTS::ENDPOINTS::BATCH_EVENTS
|
40
|
+
account_id = query_params[:a]
|
41
|
+
resp = VWO::Utils::Request.post(url, query_params, impression)
|
42
|
+
if resp.code == '200'
|
43
|
+
@logger.log(
|
44
|
+
LogLevelEnum::INFO,
|
45
|
+
format(
|
46
|
+
LogMessageEnum::InfoMessages::BULK_IMPRESSION_SUCCESS,
|
47
|
+
file: FileNameEnum::BatchEventsDispatcher,
|
48
|
+
end_point: url,
|
49
|
+
a: account_id
|
50
|
+
)
|
51
|
+
)
|
52
|
+
message = nil
|
53
|
+
elsif resp.code == '413'
|
54
|
+
@logger.log(
|
55
|
+
LogLevelEnum::DEBUG,
|
56
|
+
format(
|
57
|
+
LogMessageEnum::DebugMessages::BATCH_EVENT_LIMIT_EXCEEDED,
|
58
|
+
file: FileNameEnum::BatchEventsDispatcher,
|
59
|
+
end_point: url,
|
60
|
+
accountId: impression[:a],
|
61
|
+
eventsPerRequest: impression.length()
|
62
|
+
)
|
63
|
+
)
|
64
|
+
|
65
|
+
@logger.log(
|
66
|
+
LogLevelEnum::ERROR,
|
67
|
+
format(
|
68
|
+
LogMessageEnum::ErrorMessages::IMPRESSION_FAILED,
|
69
|
+
file: FileNameEnum::BatchEventsDispatcher,
|
70
|
+
end_point: url
|
71
|
+
)
|
72
|
+
)
|
73
|
+
message = resp.message
|
74
|
+
else
|
75
|
+
@logger.log(
|
76
|
+
LogLevelEnum::DEBUG,
|
77
|
+
format(
|
78
|
+
LogMessageEnum::DebugMessages::BULK_NOT_PROCESSED,
|
79
|
+
file: FileNameEnum::BatchEventsDispatcher
|
80
|
+
)
|
81
|
+
)
|
82
|
+
|
83
|
+
@logger.log(
|
84
|
+
LogLevelEnum::ERROR,
|
85
|
+
format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::BatchEventsDispatcher, end_point: url)
|
86
|
+
)
|
87
|
+
message = resp.message
|
88
|
+
end
|
89
|
+
if callback
|
90
|
+
callback.call(message, impression)
|
91
|
+
end
|
92
|
+
rescue StandardError => e
|
93
|
+
@logger.log(
|
94
|
+
LogLevelEnum::DEBUG,
|
95
|
+
format(
|
96
|
+
LogMessageEnum::DebugMessages::BULK_NOT_PROCESSED,
|
97
|
+
file: FileNameEnum::BatchEventsDispatcher
|
98
|
+
)
|
99
|
+
)
|
100
|
+
|
101
|
+
@logger.log(
|
102
|
+
LogLevelEnum::ERROR,
|
103
|
+
format(LogMessageEnum::ErrorMessages::IMPRESSION_FAILED, file: FileNameEnum::BatchEventsDispatcher, end_point: url)
|
104
|
+
)
|
105
|
+
false
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,175 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
require_relative '../logger'
|
16
|
+
require_relative '../enums'
|
17
|
+
require_relative '../utils/request'
|
18
|
+
|
19
|
+
class VWO
|
20
|
+
module Services
|
21
|
+
class BatchEventsQueue
|
22
|
+
include VWO::Enums
|
23
|
+
|
24
|
+
def initialize(batch_config, is_development_mode = false)
|
25
|
+
@is_development_mode = is_development_mode
|
26
|
+
@logger = VWO::Logger.get_instance
|
27
|
+
@queue = []
|
28
|
+
@queue_metadata = {}
|
29
|
+
@batch_config = batch_config
|
30
|
+
|
31
|
+
if batch_config[:request_time_interval]
|
32
|
+
@request_time_interval = batch_config[:request_time_interval]
|
33
|
+
else
|
34
|
+
@request_time_interval = CONSTANTS::DEFAULT_REQUEST_TIME_INTERVAL
|
35
|
+
@logger.log(
|
36
|
+
LogLevelEnum::DEBUG,
|
37
|
+
format(
|
38
|
+
LogMessageEnum::DebugMessages::EVENT_BATCHING_INSUFFICIENT,
|
39
|
+
file: FileNameEnum::BatchEventsQueue,
|
40
|
+
key: 'request_time_interval'
|
41
|
+
)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
if batch_config[:events_per_request]
|
46
|
+
@events_per_request = batch_config[:events_per_request]
|
47
|
+
else
|
48
|
+
@events_per_request = CONSTANTS::DEFAULT_EVENTS_PER_REQUEST
|
49
|
+
@logger.log(
|
50
|
+
LogLevelEnum::DEBUG,
|
51
|
+
format(
|
52
|
+
LogMessageEnum::DebugMessages::EVENT_BATCHING_INSUFFICIENT,
|
53
|
+
file: FileNameEnum::BatchEventsQueue,
|
54
|
+
key: 'events_per_request'
|
55
|
+
)
|
56
|
+
)
|
57
|
+
end
|
58
|
+
|
59
|
+
@flush_callback = nil
|
60
|
+
if batch_config.key?(:flushCallback) && batch_config[:flushCallback].is_a?(Method)
|
61
|
+
@flush_callback = batch_config[:flushCallback]
|
62
|
+
end
|
63
|
+
|
64
|
+
@dispatcher = batch_config[:dispatcher]
|
65
|
+
end
|
66
|
+
|
67
|
+
def create_new_batch_timer
|
68
|
+
@timer = Time.now + @request_time_interval
|
69
|
+
end
|
70
|
+
|
71
|
+
def enqueue(event)
|
72
|
+
return true if @is_development_mode
|
73
|
+
@queue.push(event)
|
74
|
+
update_queue_metadata(event)
|
75
|
+
unless @timer
|
76
|
+
create_new_batch_timer
|
77
|
+
@thread = Thread.new{flush_when_request_times_up}
|
78
|
+
end
|
79
|
+
if @events_per_request === @queue.length()
|
80
|
+
flush
|
81
|
+
kill_old_thread
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def flush_when_request_times_up
|
86
|
+
while @timer > Time.now
|
87
|
+
sleep(1)
|
88
|
+
end
|
89
|
+
flush
|
90
|
+
kill_old_thread
|
91
|
+
end
|
92
|
+
|
93
|
+
def flush(manual = false)
|
94
|
+
if @queue.length() > 0
|
95
|
+
@logger.log(
|
96
|
+
LogLevelEnum::DEBUG,
|
97
|
+
format(
|
98
|
+
LogMessageEnum::DebugMessages::BEFORE_FLUSHING,
|
99
|
+
file: FileNameEnum::BatchEventsQueue,
|
100
|
+
manually: manual ? 'manually' : '',
|
101
|
+
length: @queue.length(),
|
102
|
+
timer: manual ? 'Timer will be cleared and registered again,' : '',
|
103
|
+
queue_metadata: @queue_metadata
|
104
|
+
)
|
105
|
+
)
|
106
|
+
|
107
|
+
@dispatcher.call(@queue, @flush_callback)
|
108
|
+
@logger.log(
|
109
|
+
LogLevelEnum::INFO,
|
110
|
+
format(
|
111
|
+
LogMessageEnum::InfoMessages::AFTER_FLUSHING,
|
112
|
+
file: FILE,
|
113
|
+
manually: manual ? 'manually,' : '',
|
114
|
+
length: @queue.length(),
|
115
|
+
queue_metadata: @queue_metadata
|
116
|
+
)
|
117
|
+
)
|
118
|
+
@queue_metadata = {}
|
119
|
+
@queue = []
|
120
|
+
else
|
121
|
+
@logger.log(
|
122
|
+
LogLevelEnum::INFO,
|
123
|
+
format(
|
124
|
+
'Batch queue is empty. Nothing to flush.',
|
125
|
+
file: FILE
|
126
|
+
)
|
127
|
+
)
|
128
|
+
end
|
129
|
+
|
130
|
+
clear_request_timer
|
131
|
+
unless manual
|
132
|
+
if @thread
|
133
|
+
@old_thread = @thread
|
134
|
+
end
|
135
|
+
end
|
136
|
+
true
|
137
|
+
end
|
138
|
+
|
139
|
+
def clear_request_timer
|
140
|
+
@timer = nil
|
141
|
+
end
|
142
|
+
|
143
|
+
def kill_thread
|
144
|
+
if @thread
|
145
|
+
@thread.kill
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
def kill_old_thread
|
150
|
+
if @old_thread
|
151
|
+
@old_thread.kill
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
def update_queue_metadata(event)
|
156
|
+
if event[:eT] == 1
|
157
|
+
unless @queue_metadata.key?(VWO::EVENTS::TRACK_USER)
|
158
|
+
@queue_metadata[VWO::EVENTS::TRACK_USER] = 0
|
159
|
+
end
|
160
|
+
@queue_metadata[VWO::EVENTS::TRACK_USER] = @queue_metadata[VWO::EVENTS::TRACK_USER] + 1
|
161
|
+
elsif event[:eT] == 2
|
162
|
+
unless @queue_metadata.key?(VWO::EVENTS::TRACK_GOAL)
|
163
|
+
@queue_metadata[VWO::EVENTS::TRACK_GOAL] = 0
|
164
|
+
end
|
165
|
+
@queue_metadata[VWO::EVENTS::TRACK_GOAL] = @queue_metadata[VWO::EVENTS::TRACK_GOAL] + 1
|
166
|
+
elsif event[:eT] == 3
|
167
|
+
unless @queue_metadata.key?(VWO::EVENTS::PUSH)
|
168
|
+
@queue_metadata[VWO::EVENTS::PUSH] = 0
|
169
|
+
end
|
170
|
+
@queue_metadata[VWO::EVENTS::PUSH] = @queue_metadata[VWO::EVENTS::PUSH] + 1
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2019-
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -48,18 +48,6 @@ class VWO
|
|
48
48
|
|
49
49
|
resp = VWO::Utils::Request.get(impression['url'], modified_event)
|
50
50
|
if resp.code == '200'
|
51
|
-
@logger.log(
|
52
|
-
LogLevelEnum::INFO,
|
53
|
-
format(
|
54
|
-
LogMessageEnum::InfoMessages::IMPRESSION_SUCCESS,
|
55
|
-
file: FileNameEnum::EventDispatcher,
|
56
|
-
end_point: impression[:url],
|
57
|
-
campaign_id: impression[:experiment_id],
|
58
|
-
user_id: impression[:uId],
|
59
|
-
account_id: impression[:account_id],
|
60
|
-
variation_id: impression[:combination]
|
61
|
-
)
|
62
|
-
)
|
63
51
|
true
|
64
52
|
else
|
65
53
|
@logger.log(
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# Copyright 2019-2021 Wingify Software Pvt. Ltd.
|
2
|
+
#
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
# you may not use this file except in compliance with the License.
|
5
|
+
# You may obtain a copy of the License at
|
6
|
+
#
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
#
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
# See the License for the specific language governing permissions and
|
13
|
+
# limitations under the License.
|
14
|
+
|
15
|
+
class VWO
|
16
|
+
module Services
|
17
|
+
class HooksManager
|
18
|
+
# Hooks Manager is responsible for triggering callbacks useful to the end-user based on certain lifecycle events.
|
19
|
+
# Possible use with integrations when the user intends to send an event when a visitor is part of the experiment.
|
20
|
+
def initialize(config)
|
21
|
+
@logger = VWO::Logger.get_instance
|
22
|
+
if config.key?(:integrations) && config[:integrations].key?(:callback) && config[:integrations][:callback].is_a?(Method)
|
23
|
+
@callback = config[:integrations][:callback]
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# Executes the callback
|
28
|
+
# @param[Hash] properties Properties from the callback
|
29
|
+
def execute(properties)
|
30
|
+
if @callback
|
31
|
+
@callback.call(properties)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|