vwo-fme-ruby-sdk 1.2.0 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/resources/debug_messages.json +8 -1
- data/lib/resources/error_messages.json +5 -1
- data/lib/resources/info_messages.json +9 -1
- data/lib/vwo/api/get_flag.rb +30 -27
- data/lib/vwo/api/set_attribute.rb +10 -3
- data/lib/vwo/api/track_event.rb +11 -3
- data/lib/vwo/constants/constants.rb +6 -2
- data/lib/vwo/decorators/storage_decorator.rb +1 -1
- data/lib/vwo/enums/api_enum.rb +1 -1
- data/lib/vwo/enums/campaign_type_enum.rb +1 -1
- data/lib/vwo/enums/decision_types_enum.rb +1 -1
- data/lib/vwo/enums/event_enum.rb +1 -1
- data/lib/vwo/enums/headers_enum.rb +1 -1
- data/lib/vwo/enums/hooks_enum.rb +1 -1
- data/lib/vwo/enums/http_method_enum.rb +1 -1
- data/lib/vwo/enums/log_level_enum.rb +1 -1
- data/lib/vwo/enums/status_enum.rb +1 -1
- data/lib/vwo/enums/storage_enum.rb +1 -1
- data/lib/vwo/enums/url_enum.rb +2 -1
- data/lib/vwo/models/campaign/campaign_model.rb +1 -1
- data/lib/vwo/models/campaign/feature_model.rb +1 -1
- data/lib/vwo/models/campaign/impact_campaign_model.rb +1 -1
- data/lib/vwo/models/campaign/metric_model.rb +1 -1
- data/lib/vwo/models/campaign/rule_model.rb +1 -1
- data/lib/vwo/models/campaign/variable_model.rb +1 -1
- data/lib/vwo/models/campaign/variation_model.rb +1 -1
- data/lib/vwo/models/gateway_service_model.rb +1 -1
- data/lib/vwo/models/schemas/settings_schema_validation.rb +1 -1
- data/lib/vwo/models/settings/settings_model.rb +8 -2
- data/lib/vwo/models/storage/storage_data_model.rb +1 -1
- data/lib/vwo/models/user/context_model.rb +1 -1
- data/lib/vwo/models/user/context_vwo_model.rb +1 -1
- data/lib/vwo/models/user/get_flag_response.rb +1 -1
- data/lib/vwo/models/vwo_options_model.rb +1 -1
- data/lib/vwo/packages/decision_maker/decision_maker.rb +1 -1
- data/lib/vwo/packages/logger/core/log_manager.rb +1 -1
- data/lib/vwo/packages/logger/core/transport_manager.rb +1 -1
- data/lib/vwo/packages/logger/log_message_builder.rb +1 -1
- data/lib/vwo/packages/logger/logger.rb +1 -1
- data/lib/vwo/packages/logger/transports/console_transport.rb +1 -1
- data/lib/vwo/packages/network_layer/client/network_client.rb +39 -25
- data/lib/vwo/packages/network_layer/handlers/request_handler.rb +1 -1
- data/lib/vwo/packages/network_layer/manager/network_manager.rb +6 -4
- data/lib/vwo/packages/network_layer/models/global_request_model.rb +1 -1
- data/lib/vwo/packages/network_layer/models/request_model.rb +1 -1
- data/lib/vwo/packages/network_layer/models/response_model.rb +9 -1
- data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +1 -1
- data/lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb +1 -1
- data/lib/vwo/packages/storage/connector.rb +1 -1
- data/lib/vwo/packages/storage/storage.rb +3 -1
- data/lib/vwo/services/batch_event_queue.rb +179 -0
- data/lib/vwo/services/campaign_decision_service.rb +1 -1
- data/lib/vwo/services/hooks_service.rb +1 -1
- data/lib/vwo/services/logger_service.rb +1 -1
- data/lib/vwo/services/settings_service.rb +4 -2
- data/lib/vwo/services/storage_service.rb +1 -1
- data/lib/vwo/utils/batch_event_dispatcher.rb +117 -0
- data/lib/vwo/utils/campaign_util.rb +1 -1
- data/lib/vwo/utils/data_type_util.rb +1 -1
- data/lib/vwo/utils/decision_util.rb +1 -1
- data/lib/vwo/utils/function_util.rb +5 -1
- data/lib/vwo/utils/gateway_service_util.rb +1 -1
- data/lib/vwo/utils/impression_util.rb +10 -3
- data/lib/vwo/utils/log_message_util.rb +1 -1
- data/lib/vwo/utils/meg_util.rb +1 -1
- data/lib/vwo/utils/network_util.rb +16 -7
- data/lib/vwo/utils/rule_evaluation_util.rb +1 -1
- data/lib/vwo/utils/settings_util.rb +1 -1
- data/lib/vwo/utils/url_util.rb +1 -1
- data/lib/vwo/utils/uuid_util.rb +1 -1
- data/lib/vwo/vwo_builder.rb +97 -24
- data/lib/vwo/vwo_client.rb +23 -4
- data/lib/vwo.rb +2 -1
- metadata +4 -2
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -69,10 +69,12 @@ class NetworkManager
|
|
69
69
|
begin
|
70
70
|
network_options = create_request(request)
|
71
71
|
raise 'No URL found' if network_options.get_url.nil?
|
72
|
-
|
73
|
-
@client.post(network_options)
|
72
|
+
|
73
|
+
response = @client.post(network_options) # Return the response
|
74
|
+
response
|
74
75
|
rescue => e
|
75
76
|
LoggerService.log(LogLevelEnum::ERROR, "Error posting: #{e.message}", nil)
|
77
|
+
return ResponseModel.new.set_error(e.message) # Return error response
|
76
78
|
end
|
77
|
-
end
|
79
|
+
end
|
78
80
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -41,5 +41,13 @@ class ResponseModel
|
|
41
41
|
def set_error(error)
|
42
42
|
@error = error
|
43
43
|
end
|
44
|
+
|
45
|
+
def get_error
|
46
|
+
@error
|
47
|
+
end
|
48
|
+
|
49
|
+
def get_status_code
|
50
|
+
@status_code
|
51
|
+
end
|
44
52
|
end
|
45
53
|
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -18,9 +18,11 @@ class Storage
|
|
18
18
|
@instance = nil
|
19
19
|
|
20
20
|
attr_reader :connector
|
21
|
+
attr_accessor :is_storage_enabled
|
21
22
|
|
22
23
|
def initialize
|
23
24
|
@connector = nil
|
25
|
+
@is_storage_enabled = false
|
24
26
|
end
|
25
27
|
|
26
28
|
# Attach a connector (can be an instance or a class)
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Copyright 2024-2025 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 '../utils/data_type_util'
|
16
|
+
require_relative '../services/logger_service'
|
17
|
+
require_relative '../enums/log_level_enum'
|
18
|
+
require_relative '../constants/constants'
|
19
|
+
require_relative '../packages/network_layer/manager/network_manager'
|
20
|
+
require 'concurrent'
|
21
|
+
|
22
|
+
class BatchEventsQueue
|
23
|
+
class << self
|
24
|
+
def instance
|
25
|
+
@instance ||= nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def configure(batch_config)
|
29
|
+
@instance = new(batch_config)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
# Initializes a new batch events queue with the specified configuration
|
33
|
+
# @param batch_config Configuration object containing:
|
34
|
+
# - request_time_interval: Time interval between batch requests (in seconds)
|
35
|
+
# - events_per_request: Maximum number of events to include in a single request
|
36
|
+
# - flush_callback: Callback function to execute after flushing events
|
37
|
+
# - dispatcher: Function to handle sending the batched events
|
38
|
+
def initialize(batch_config)
|
39
|
+
@queue = []
|
40
|
+
@batch_config = batch_config
|
41
|
+
@network_client = NetworkManager.instance.get_client
|
42
|
+
|
43
|
+
if DataTypeUtil.is_number(batch_config[:request_time_interval]) && batch_config[:request_time_interval] >= 1
|
44
|
+
@request_time_interval = batch_config[:request_time_interval]
|
45
|
+
else
|
46
|
+
@request_time_interval = Constants::DEFAULT_REQUEST_TIME_INTERVAL
|
47
|
+
LoggerService.log(LogLevelEnum::INFO, "EVENT_BATCH_DEFAULTS", {
|
48
|
+
parameter: 'request_time_interval',
|
49
|
+
minLimit: 0,
|
50
|
+
defaultValue: "#{@request_time_interval} seconds"
|
51
|
+
})
|
52
|
+
end
|
53
|
+
|
54
|
+
if DataTypeUtil.is_number(batch_config[:events_per_request]) &&
|
55
|
+
batch_config[:events_per_request] > 0 &&
|
56
|
+
batch_config[:events_per_request] <= Constants::MAX_EVENTS_PER_REQUEST
|
57
|
+
@events_per_request = batch_config[:events_per_request]
|
58
|
+
elsif DataTypeUtil.is_number(batch_config[:events_per_request]) &&
|
59
|
+
batch_config[:events_per_request] > Constants::MAX_EVENTS_PER_REQUEST
|
60
|
+
@events_per_request = Constants::MAX_EVENTS_PER_REQUEST
|
61
|
+
LoggerService.log(LogLevelEnum::INFO, "EVENT_BATCH_MAX_LIMIT", {
|
62
|
+
parameter: 'events_per_request',
|
63
|
+
maxLimit: Constants::MAX_EVENTS_PER_REQUEST.to_s
|
64
|
+
})
|
65
|
+
else
|
66
|
+
@events_per_request = Constants::DEFAULT_EVENTS_PER_REQUEST
|
67
|
+
LoggerService.log(LogLevelEnum::INFO, "EVENT_BATCH_DEFAULTS", {
|
68
|
+
parameter: 'events_per_request',
|
69
|
+
minLimit: 0,
|
70
|
+
defaultValue: @events_per_request.to_s
|
71
|
+
})
|
72
|
+
end
|
73
|
+
|
74
|
+
@flush_callback = batch_config[:flush_callback] if batch_config[:flush_callback].respond_to?(:call)
|
75
|
+
|
76
|
+
@dispatcher = batch_config[:dispatcher]
|
77
|
+
@batch_lock = Mutex.new
|
78
|
+
@timer = nil
|
79
|
+
create_new_batch_timer
|
80
|
+
end
|
81
|
+
|
82
|
+
# Creates a new timer thread to automatically flush events after request_time_interval
|
83
|
+
# The timer is only created if one doesn't already exist
|
84
|
+
def create_new_batch_timer
|
85
|
+
return if @timer
|
86
|
+
|
87
|
+
@timer = Time.now + @request_time_interval
|
88
|
+
@thread = Thread.new { flush_when_request_times_up }
|
89
|
+
end
|
90
|
+
|
91
|
+
# Adds a new event to the queue and manages batch processing
|
92
|
+
# If queue reaches events_per_request limit, it triggers an immediate flush
|
93
|
+
# @param event The event to be added to the queue
|
94
|
+
def enqueue(event)
|
95
|
+
@queue.push(event)
|
96
|
+
|
97
|
+
LoggerService.log(LogLevelEnum::INFO, "EVENT_QUEUE", {
|
98
|
+
queueType: 'batch',
|
99
|
+
event: event.to_json
|
100
|
+
})
|
101
|
+
|
102
|
+
# if the number of events in the queue is equal to the events_per_request, flush
|
103
|
+
if @queue.length >= @events_per_request
|
104
|
+
flush
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Background thread function that monitors the timer
|
109
|
+
# When the timer expires, it flushes the queue and cleans up
|
110
|
+
def flush_when_request_times_up
|
111
|
+
sleep(1) while @timer && Time.now < @timer
|
112
|
+
flush
|
113
|
+
end
|
114
|
+
|
115
|
+
# Processes and sends all queued events
|
116
|
+
# @param manual Boolean indicating if flush was triggered manually
|
117
|
+
# Clears the queue after successful processing
|
118
|
+
def flush(manual = false)
|
119
|
+
@batch_lock.synchronize do
|
120
|
+
if @queue.any?
|
121
|
+
LoggerService.log(LogLevelEnum::DEBUG, "EVENT_BATCH_BEFORE_FLUSHING", {
|
122
|
+
manually: manual ? 'manually' : '',
|
123
|
+
length: @queue.length,
|
124
|
+
accountId: @batch_config[:account_id],
|
125
|
+
timer: manual ? 'Timer will be cleared and registered again' : ''
|
126
|
+
})
|
127
|
+
|
128
|
+
# add events to another queue
|
129
|
+
temp_queue = @queue.dup
|
130
|
+
@queue = []
|
131
|
+
|
132
|
+
if manual
|
133
|
+
future = Concurrent::Future.new(executor: @network_client.get_thread_pool) do
|
134
|
+
handle_flush_response(temp_queue, manual)
|
135
|
+
end
|
136
|
+
future.execute
|
137
|
+
@response = future.value
|
138
|
+
else
|
139
|
+
@network_client.get_thread_pool.post do
|
140
|
+
handle_flush_response(temp_queue, manual)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
else
|
144
|
+
LoggerService.log(LogLevelEnum::DEBUG, "BATCH_QUEUE_EMPTY")
|
145
|
+
@response = {status: "success", events: []}
|
146
|
+
end
|
147
|
+
kill_old_thread if !manual && @thread
|
148
|
+
clear_request_timer
|
149
|
+
create_new_batch_timer
|
150
|
+
@response
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
private
|
155
|
+
|
156
|
+
def handle_flush_response(temp_queue, manual)
|
157
|
+
@response = @dispatcher.call(temp_queue, @flush_callback)
|
158
|
+
if @response[:status] == "success"
|
159
|
+
LoggerService.log(LogLevelEnum::INFO, "EVENT_BATCH_After_FLUSHING", {
|
160
|
+
manually: manual ? 'manually' : '',
|
161
|
+
length: temp_queue.length
|
162
|
+
})
|
163
|
+
else
|
164
|
+
@queue.concat(temp_queue)
|
165
|
+
end
|
166
|
+
temp_queue = []
|
167
|
+
@response
|
168
|
+
end
|
169
|
+
|
170
|
+
# Resets the request timer to nil
|
171
|
+
def clear_request_timer
|
172
|
+
@timer = nil
|
173
|
+
end
|
174
|
+
|
175
|
+
def kill_old_thread
|
176
|
+
@old_thread&.kill
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -23,7 +23,7 @@ require_relative '../enums/log_level_enum'
|
|
23
23
|
require_relative '../models/schemas/settings_schema_validation'
|
24
24
|
|
25
25
|
class SettingsService
|
26
|
-
attr_accessor :sdk_key, :account_id, :expiry, :network_timeout, :hostname, :port, :protocol, :is_gateway_service_provided
|
26
|
+
attr_accessor :sdk_key, :account_id, :expiry, :network_timeout, :hostname, :port, :protocol, :is_gateway_service_provided, :is_settings_valid
|
27
27
|
|
28
28
|
class << self
|
29
29
|
attr_accessor :instance
|
@@ -38,6 +38,7 @@ class SettingsService
|
|
38
38
|
@account_id = options[:account_id]
|
39
39
|
@expiry = options.dig(:settings, :expiry) || Constants::SETTINGS_EXPIRY
|
40
40
|
@network_timeout = options.dig(:settings, :timeout) || Constants::SETTINGS_TIMEOUT
|
41
|
+
@is_settings_valid = false
|
41
42
|
|
42
43
|
if options[:gateway_service] && options[:gateway_service][:url]
|
43
44
|
parsed_url = URI.parse(options[:gateway_service][:url].start_with?(Constants::HTTP_PROTOCOL) || options[:gateway_service][:url].start_with?(Constants::HTTPS_PROTOCOL) ? options[:gateway_service][:url] : "#{Constants::HTTPS_PROTOCOL}#{options[:gateway_service][:url]}")
|
@@ -109,6 +110,7 @@ class SettingsService
|
|
109
110
|
settings = fetch_settings_and_cache_in_storage
|
110
111
|
is_valid = SettingsSchema.new.is_settings_valid(settings)
|
111
112
|
if is_valid
|
113
|
+
@is_settings_valid = true
|
112
114
|
LoggerService.log(LogLevelEnum::INFO, "SETTINGS_FETCH_SUCCESS")
|
113
115
|
settings
|
114
116
|
else
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# Copyright 2024-2025 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 './network_util'
|
16
|
+
require_relative '../enums/http_method_enum'
|
17
|
+
require_relative '../enums/url_enum'
|
18
|
+
require_relative '../enums/log_level_enum'
|
19
|
+
require_relative '../services/logger_service'
|
20
|
+
require_relative '../packages/network_layer/manager/network_manager'
|
21
|
+
require_relative '../packages/network_layer/models/request_model'
|
22
|
+
|
23
|
+
class BatchEventDispatcher
|
24
|
+
|
25
|
+
class << self
|
26
|
+
|
27
|
+
# Dispatches a batch of events to the VWO server
|
28
|
+
# @param properties [Hash] The event properties to send
|
29
|
+
# @param callback [Proc] Optional callback function to execute after the request (defaults to empty proc)
|
30
|
+
# @param query_params [Hash] Query parameters to include in the request
|
31
|
+
def dispatch(properties, callback = -> {}, query_params)
|
32
|
+
# Send the prepared payload via POST API request
|
33
|
+
send_batch_post_api_request(query_params, properties, callback)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Sends a POST API request with given properties and payload
|
37
|
+
def send_batch_post_api_request(properties, payload, callback)
|
38
|
+
network_instance = NetworkManager.instance
|
39
|
+
headers = {}
|
40
|
+
headers['Authorization'] = "#{SettingsService.instance.sdk_key}"
|
41
|
+
|
42
|
+
request = RequestModel.new(
|
43
|
+
UrlUtil.get_base_url,
|
44
|
+
HttpMethodEnum::POST,
|
45
|
+
UrlEnum::BATCH_EVENTS,
|
46
|
+
properties,
|
47
|
+
payload,
|
48
|
+
headers,
|
49
|
+
SettingsService.instance.protocol,
|
50
|
+
SettingsService.instance.port
|
51
|
+
)
|
52
|
+
|
53
|
+
begin
|
54
|
+
response = network_instance.post(request)
|
55
|
+
handle_batch_response(UrlEnum::BATCH_EVENTS, payload, properties, response, response.get_data, callback)
|
56
|
+
rescue StandardError => err
|
57
|
+
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
58
|
+
method: "#{HttpMethodEnum::POST} #{UrlEnum::BATCH_EVENTS}",
|
59
|
+
err: err.is_a?(Hash) ? err.to_json : err
|
60
|
+
})
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Handles the response from a batch event API call
|
65
|
+
# @param end_point [String] The API endpoint that was called
|
66
|
+
# @param payload [Hash] The payload that was sent in the request
|
67
|
+
# @param query_params [Hash] The query parameters used in the request
|
68
|
+
# @param res [ResponseModel] The response object from the API call
|
69
|
+
# @param raw_data [String] The raw response data from the API
|
70
|
+
# @param callback [Proc] Optional callback to be executed after handling the response
|
71
|
+
def handle_batch_response(end_point, payload, query_params, res, raw_data, callback)
|
72
|
+
events_per_request = payload[:ev].length
|
73
|
+
account_id = query_params[:a]
|
74
|
+
|
75
|
+
error = res.get_error
|
76
|
+
if error
|
77
|
+
LoggerService.log(LogLevelEnum::INFO, "IMPRESSION_BATCH_FAILED")
|
78
|
+
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
79
|
+
method: "#{HttpMethodEnum::POST} #{UrlEnum::BATCH_EVENTS}",
|
80
|
+
err: error
|
81
|
+
})
|
82
|
+
callback.call(error, payload.to_json) if callback.respond_to?(:call)
|
83
|
+
return {status: "error", events: payload}
|
84
|
+
else
|
85
|
+
case res.get_status_code
|
86
|
+
when 200
|
87
|
+
LoggerService.log(LogLevelEnum::INFO, "IMPRESSION_BATCH_SUCCESS", {
|
88
|
+
accountId: account_id,
|
89
|
+
endPoint: end_point,
|
90
|
+
})
|
91
|
+
callback.call(nil, payload.to_json) if callback.respond_to?(:call)
|
92
|
+
return {status: "success", events: payload}
|
93
|
+
when 413
|
94
|
+
LoggerService.log(LogLevelEnum::DEBUG, "CONFIG_BATCH_EVENT_LIMIT_EXCEEDED", {
|
95
|
+
accountId: account_id,
|
96
|
+
endPoint: end_point,
|
97
|
+
eventsPerRequest: events_per_request
|
98
|
+
})
|
99
|
+
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
100
|
+
method: "#{HttpMethodEnum::POST} #{UrlEnum::BATCH_EVENTS}",
|
101
|
+
err: error
|
102
|
+
})
|
103
|
+
callback.call(error, payload.to_json) if callback.respond_to?(:call)
|
104
|
+
return {status: "error", events: payload}
|
105
|
+
else
|
106
|
+
LoggerService.log(LogLevelEnum::INFO, "IMPRESSION_BATCH_FAILED")
|
107
|
+
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
108
|
+
method: "#{HttpMethodEnum::POST} #{UrlEnum::BATCH_EVENTS}",
|
109
|
+
err: error
|
110
|
+
})
|
111
|
+
callback.call(error, payload.to_json) if callback.respond_to?(:call)
|
112
|
+
return {status: "error", events: payload}
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -17,6 +17,10 @@ require_relative '../models/campaign/campaign_model'
|
|
17
17
|
require_relative '../models/campaign/feature_model'
|
18
18
|
require_relative '../models/settings/settings_model'
|
19
19
|
require_relative '../utils/data_type_util'
|
20
|
+
require_relative '../services/logger_service'
|
21
|
+
require_relative '../enums/log_level_enum'
|
22
|
+
require_relative '../constants/constants'
|
23
|
+
require_relative '../utils/data_type_util'
|
20
24
|
|
21
25
|
# Clones an object deeply.
|
22
26
|
# @param obj [Object] The object to clone.
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -16,7 +16,7 @@ require_relative '../models/settings/settings_model'
|
|
16
16
|
require_relative './network_util'
|
17
17
|
require_relative '../models/user/context_model'
|
18
18
|
require_relative '../enums/event_enum'
|
19
|
-
|
19
|
+
require_relative '../services/batch_event_queue'
|
20
20
|
# Creates and sends an impression for a variation shown event.
|
21
21
|
# This function constructs the necessary properties and payload for the event
|
22
22
|
# and uses the NetworkUtil to send a POST API request.
|
@@ -45,5 +45,12 @@ def create_and_send_impression_for_variation_shown(settings, campaign_id, variat
|
|
45
45
|
context.get_ip_address
|
46
46
|
)
|
47
47
|
|
48
|
-
|
48
|
+
# check if batching is enabled
|
49
|
+
if BatchEventsQueue.instance
|
50
|
+
# add the payload to the batch events queue
|
51
|
+
BatchEventsQueue.instance.enqueue(payload)
|
52
|
+
else
|
53
|
+
# Send the constructed payload via POST request
|
54
|
+
NetworkUtil.send_post_api_request(properties, payload)
|
55
|
+
end
|
49
56
|
end
|
data/lib/vwo/utils/meg_util.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright 2025 Wingify Software Pvt. Ltd.
|
1
|
+
# Copyright 2024-2025 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.
|
@@ -104,8 +104,6 @@ class NetworkUtil
|
|
104
104
|
msgId: "#{uuid}-#{get_current_unix_timestamp_in_millis}",
|
105
105
|
visId: uuid,
|
106
106
|
sessionId: get_current_unix_timestamp,
|
107
|
-
visitor_ua: visitor_user_agent,
|
108
|
-
visitor_ip: ip_address,
|
109
107
|
event: {
|
110
108
|
props: {
|
111
109
|
vwo_sdkName: Constants::SDK_NAME,
|
@@ -130,6 +128,10 @@ class NetworkUtil
|
|
130
128
|
properties[:d][:event][:props][:id] = campaign_id
|
131
129
|
properties[:d][:event][:props][:variation] = variation_id
|
132
130
|
properties[:d][:event][:props][:isFirst] = 1
|
131
|
+
|
132
|
+
# Only add visitor_ua and visitor_ip if they are non-null
|
133
|
+
properties[:d][:visitor_ua] = visitor_user_agent if visitor_user_agent && !visitor_user_agent.empty?
|
134
|
+
properties[:d][:visitor_ip] = ip_address if ip_address && !ip_address.empty?
|
133
135
|
|
134
136
|
LoggerService.log(LogLevelEnum::DEBUG, "IMPRESSION_FOR_TRACK_USER", {
|
135
137
|
accountId: settings.account_id,
|
@@ -196,9 +198,16 @@ class NetworkUtil
|
|
196
198
|
SettingsService.instance.protocol,
|
197
199
|
SettingsService.instance.port
|
198
200
|
)
|
199
|
-
|
200
|
-
begin
|
201
|
-
network_instance.
|
201
|
+
|
202
|
+
begin
|
203
|
+
if network_instance.get_client.get_should_use_threading
|
204
|
+
network_instance.get_client.get_thread_pool.post {
|
205
|
+
response = network_instance.post(request)
|
206
|
+
response
|
207
|
+
}
|
208
|
+
else
|
209
|
+
response = network_instance.post(request)
|
210
|
+
end
|
202
211
|
rescue ResponseModel => err
|
203
212
|
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
204
213
|
method: HttpMethodEnum::POST,
|
@@ -224,7 +233,7 @@ class NetworkUtil
|
|
224
233
|
|
225
234
|
begin
|
226
235
|
network_instance.get(request)
|
227
|
-
rescue
|
236
|
+
rescue StandardError => err
|
228
237
|
LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
|
229
238
|
method: HttpMethodEnum::GET,
|
230
239
|
err: err.is_a?(Hash) ? err.to_json : err
|
data/lib/vwo/utils/url_util.rb
CHANGED
data/lib/vwo/utils/uuid_util.rb
CHANGED