vwo-fme-ruby-sdk 1.2.0 → 1.3.1

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.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/resources/debug_messages.json +8 -1
  3. data/lib/resources/error_messages.json +5 -1
  4. data/lib/resources/info_messages.json +9 -1
  5. data/lib/vwo/api/get_flag.rb +30 -27
  6. data/lib/vwo/api/set_attribute.rb +10 -3
  7. data/lib/vwo/api/track_event.rb +11 -3
  8. data/lib/vwo/constants/constants.rb +6 -2
  9. data/lib/vwo/decorators/storage_decorator.rb +1 -1
  10. data/lib/vwo/enums/api_enum.rb +1 -1
  11. data/lib/vwo/enums/campaign_type_enum.rb +1 -1
  12. data/lib/vwo/enums/decision_types_enum.rb +1 -1
  13. data/lib/vwo/enums/event_enum.rb +1 -1
  14. data/lib/vwo/enums/headers_enum.rb +1 -1
  15. data/lib/vwo/enums/hooks_enum.rb +1 -1
  16. data/lib/vwo/enums/http_method_enum.rb +1 -1
  17. data/lib/vwo/enums/log_level_enum.rb +1 -1
  18. data/lib/vwo/enums/log_level_to_number.rb +27 -0
  19. data/lib/vwo/enums/status_enum.rb +1 -1
  20. data/lib/vwo/enums/storage_enum.rb +1 -1
  21. data/lib/vwo/enums/url_enum.rb +2 -1
  22. data/lib/vwo/models/campaign/campaign_model.rb +1 -1
  23. data/lib/vwo/models/campaign/feature_model.rb +1 -1
  24. data/lib/vwo/models/campaign/impact_campaign_model.rb +1 -1
  25. data/lib/vwo/models/campaign/metric_model.rb +1 -1
  26. data/lib/vwo/models/campaign/rule_model.rb +1 -1
  27. data/lib/vwo/models/campaign/variable_model.rb +1 -1
  28. data/lib/vwo/models/campaign/variation_model.rb +1 -1
  29. data/lib/vwo/models/gateway_service_model.rb +1 -1
  30. data/lib/vwo/models/schemas/settings_schema_validation.rb +1 -1
  31. data/lib/vwo/models/settings/settings_model.rb +8 -2
  32. data/lib/vwo/models/storage/storage_data_model.rb +1 -1
  33. data/lib/vwo/models/user/context_model.rb +1 -1
  34. data/lib/vwo/models/user/context_vwo_model.rb +1 -1
  35. data/lib/vwo/models/user/get_flag_response.rb +1 -1
  36. data/lib/vwo/models/vwo_options_model.rb +13 -2
  37. data/lib/vwo/packages/decision_maker/decision_maker.rb +1 -1
  38. data/lib/vwo/packages/logger/core/log_manager.rb +1 -1
  39. data/lib/vwo/packages/logger/core/transport_manager.rb +4 -15
  40. data/lib/vwo/packages/logger/log_message_builder.rb +1 -1
  41. data/lib/vwo/packages/logger/logger.rb +1 -1
  42. data/lib/vwo/packages/logger/transports/console_transport.rb +1 -1
  43. data/lib/vwo/packages/network_layer/client/network_client.rb +39 -25
  44. data/lib/vwo/packages/network_layer/handlers/request_handler.rb +1 -1
  45. data/lib/vwo/packages/network_layer/manager/network_manager.rb +6 -4
  46. data/lib/vwo/packages/network_layer/models/global_request_model.rb +1 -1
  47. data/lib/vwo/packages/network_layer/models/request_model.rb +1 -1
  48. data/lib/vwo/packages/network_layer/models/response_model.rb +9 -1
  49. data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +1 -1
  50. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +1 -1
  51. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +1 -1
  52. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +1 -1
  53. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +1 -1
  54. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +1 -1
  55. data/lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb +1 -1
  56. data/lib/vwo/packages/storage/connector.rb +1 -1
  57. data/lib/vwo/packages/storage/storage.rb +3 -1
  58. data/lib/vwo/services/batch_event_queue.rb +179 -0
  59. data/lib/vwo/services/campaign_decision_service.rb +1 -1
  60. data/lib/vwo/services/hooks_service.rb +1 -1
  61. data/lib/vwo/services/logger_service.rb +1 -1
  62. data/lib/vwo/services/settings_service.rb +4 -2
  63. data/lib/vwo/services/storage_service.rb +1 -1
  64. data/lib/vwo/utils/batch_event_dispatcher.rb +117 -0
  65. data/lib/vwo/utils/campaign_util.rb +1 -1
  66. data/lib/vwo/utils/data_type_util.rb +1 -1
  67. data/lib/vwo/utils/decision_util.rb +1 -1
  68. data/lib/vwo/utils/function_util.rb +5 -1
  69. data/lib/vwo/utils/gateway_service_util.rb +1 -1
  70. data/lib/vwo/utils/impression_util.rb +10 -3
  71. data/lib/vwo/utils/log_message_util.rb +1 -1
  72. data/lib/vwo/utils/meg_util.rb +1 -1
  73. data/lib/vwo/utils/network_util.rb +31 -8
  74. data/lib/vwo/utils/rule_evaluation_util.rb +1 -1
  75. data/lib/vwo/utils/settings_util.rb +1 -1
  76. data/lib/vwo/utils/url_util.rb +1 -1
  77. data/lib/vwo/utils/usage_stats_util.rb +117 -0
  78. data/lib/vwo/utils/uuid_util.rb +1 -1
  79. data/lib/vwo/vwo_builder.rb +107 -24
  80. data/lib/vwo/vwo_client.rb +23 -4
  81. data/lib/vwo.rb +3 -1
  82. metadata +6 -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.
@@ -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
- NetworkUtil.send_post_api_request(properties, payload)
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
@@ -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.
@@ -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.
@@ -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,6 +23,7 @@ require_relative '../packages/network_layer/models/request_model'
23
23
  require_relative '../packages/network_layer/models/response_model'
24
24
  require_relative '../utils/url_util'
25
25
  require_relative '../utils/uuid_util'
26
+ require_relative '../utils/usage_stats_util'
26
27
 
27
28
  class NetworkUtil
28
29
  class << self
@@ -104,8 +105,6 @@ class NetworkUtil
104
105
  msgId: "#{uuid}-#{get_current_unix_timestamp_in_millis}",
105
106
  visId: uuid,
106
107
  sessionId: get_current_unix_timestamp,
107
- visitor_ua: visitor_user_agent,
108
- visitor_ip: ip_address,
109
108
  event: {
110
109
  props: {
111
110
  vwo_sdkName: Constants::SDK_NAME,
@@ -130,6 +129,16 @@ class NetworkUtil
130
129
  properties[:d][:event][:props][:id] = campaign_id
131
130
  properties[:d][:event][:props][:variation] = variation_id
132
131
  properties[:d][:event][:props][:isFirst] = 1
132
+
133
+ # Only add visitor_ua and visitor_ip if they are non-null
134
+ properties[:d][:visitor_ua] = visitor_user_agent if visitor_user_agent && !visitor_user_agent.empty?
135
+ properties[:d][:visitor_ip] = ip_address if ip_address && !ip_address.empty?
136
+
137
+ # check if usage stats size is greater than 0
138
+ usage_stats = UsageStatsUtil.get_usage_stats
139
+ if usage_stats.size > 0
140
+ properties[:d][:event][:props][:vwoMeta] = usage_stats
141
+ end
133
142
 
134
143
  LoggerService.log(LogLevelEnum::DEBUG, "IMPRESSION_FOR_TRACK_USER", {
135
144
  accountId: settings.account_id,
@@ -196,9 +205,23 @@ class NetworkUtil
196
205
  SettingsService.instance.protocol,
197
206
  SettingsService.instance.port
198
207
  )
199
-
200
- begin
201
- network_instance.post(request)
208
+
209
+ begin
210
+ if network_instance.get_client.get_should_use_threading
211
+ network_instance.get_client.get_thread_pool.post {
212
+ response = network_instance.post(request)
213
+ if response.get_status_code == 200
214
+ UsageStatsUtil.clear_usage_stats
215
+ end
216
+ response
217
+ }
218
+ else
219
+ response = network_instance.post(request)
220
+ if response.get_status_code == 200
221
+ UsageStatsUtil.clear_usage_stats
222
+ end
223
+ response
224
+ end
202
225
  rescue ResponseModel => err
203
226
  LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
204
227
  method: HttpMethodEnum::POST,
@@ -224,7 +247,7 @@ class NetworkUtil
224
247
 
225
248
  begin
226
249
  network_instance.get(request)
227
- rescue ResponseModel => err
250
+ rescue StandardError => err
228
251
  LoggerService.log(LogLevelEnum::ERROR, "NETWORK_CALL_FAILED", {
229
252
  method: HttpMethodEnum::GET,
230
253
  err: err.is_a?(Hash) ? err.to_json : err
@@ -232,4 +255,4 @@ class NetworkUtil
232
255
  end
233
256
  end
234
257
  end
235
- end
258
+ 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.
@@ -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.
@@ -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.
@@ -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
+
16
+ require_relative '../constants/constants'
17
+ require_relative '../enums/log_level_to_number'
18
+
19
+ # Manages usage statistics for the SDK.
20
+ # Tracks various features and configurations being used by the client.
21
+ # Implements Singleton pattern to ensure a single instance.
22
+ class UsageStatsUtil
23
+ @instance = nil
24
+ @usage_stats_data = {}
25
+
26
+ class << self
27
+ # Provides access to the singleton instance of UsageStatsUtil.
28
+ #
29
+ # @return [UsageStatsUtil] The single instance of UsageStatsUtil
30
+ def instance
31
+ @instance ||= new
32
+ end
33
+
34
+ # Sets usage statistics based on provided options.
35
+ # Maps various SDK features and configurations to boolean flags.
36
+ #
37
+ # @param options [Hash] Configuration options for the SDK
38
+ def set_usage_stats(options)
39
+ instance.set_usage_stats(options)
40
+ end
41
+
42
+ # Retrieves the current usage statistics.
43
+ #
44
+ # @return [Hash] Record containing boolean flags for various SDK features in use
45
+ def get_usage_stats
46
+ instance.get_usage_stats
47
+ end
48
+
49
+ def clear_usage_stats
50
+ instance.clear_usage_stats
51
+ end
52
+ end
53
+
54
+ private_class_method :new
55
+
56
+ def initialize
57
+ @usage_stats_data = {}
58
+ end
59
+
60
+ def set_usage_stats(options)
61
+ storage = options[:storage]
62
+ logger = options[:logger]
63
+ event_batching = options[:batch_event_data]
64
+ integrations = options[:integrations]
65
+ poll_interval = options[:poll_interval]
66
+ vwo_meta = options[:_vwo_meta]
67
+ gateway_service = options[:gateway_service]
68
+ threading = options[:threading]
69
+
70
+ data = {}
71
+
72
+ data[:ig] = 1 if integrations
73
+ data[:eb] = 1 if event_batching
74
+ data[:gs] = 1 if gateway_service
75
+
76
+ # if logger has transport or transports, then it is custom logger
77
+ if logger && (logger.key?(:transport) || logger.key?(:transports))
78
+ data[:cl] = 1
79
+ end
80
+
81
+ data[:ss] = 1 if storage
82
+
83
+ if logger && logger.key?(:level)
84
+ data[:ll] = LogLevelToNumber.to_number(logger[:level]) || -1
85
+ end
86
+
87
+ data[:pi] = 1 if poll_interval
88
+
89
+ if vwo_meta && vwo_meta.key?(:ea)
90
+ data[:_ea] = 1
91
+ end
92
+
93
+ # check if threading is not passed or is if passed then enabled should be true
94
+ if !threading || (threading && threading[:enabled] == true)
95
+ data[:th] = 1
96
+ # check if max_pool_size is passed
97
+ if threading && threading[:max_pool_size]
98
+ data[:th_mps] = threading[:max_pool_size]
99
+ end
100
+ end
101
+
102
+ if defined?(RUBY_VERSION)
103
+ data[:lv] = RUBY_VERSION
104
+ end
105
+
106
+ @usage_stats_data = data
107
+ end
108
+
109
+ def get_usage_stats
110
+ @usage_stats_data
111
+ end
112
+
113
+ def clear_usage_stats
114
+ @usage_stats_data = {}
115
+ end
116
+ end
117
+
@@ -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.
@@ -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.
@@ -21,9 +21,14 @@ require_relative './packages/storage/storage'
21
21
  require_relative './packages/network_layer/manager/network_manager'
22
22
  require_relative './packages/segmentation_evaluator/core/segmentation_manager'
23
23
  require_relative './services/logger_service'
24
+ require_relative './services/batch_event_queue'
25
+ require_relative './utils/function_util'
26
+ require_relative './utils/batch_event_dispatcher'
27
+ require_relative './constants/constants'
28
+ require_relative './utils/usage_stats_util'
24
29
 
25
30
  class VWOBuilder
26
- attr_reader :settings, :storage, :log_manager, :is_settings_fetch_in_progress, :vwo_instance
31
+ attr_reader :settings, :storage, :log_manager, :is_settings_fetch_in_progress, :vwo_instance, :is_valid_poll_interval_passed_from_init
27
32
 
28
33
  # Initialize the VWOBuilder with the given options
29
34
  # @param options [Hash] The options for the VWOBuilder
@@ -33,9 +38,50 @@ class VWOBuilder
33
38
  @storage = nil
34
39
  @log_manager = nil
35
40
  @is_settings_fetch_in_progress = false
41
+ @is_valid_poll_interval_passed_from_init = false
36
42
  @vwo_instance = nil
37
43
  end
38
44
 
45
+ # Initializes the batch event processing system
46
+ # Validates batch event settings and configures the BatchEventsQueue
47
+ # Sets up event dispatcher and flushes any existing events
48
+ # @raise [StandardError] If batch event configuration is invalid
49
+ def init_batch
50
+ # if gateway service is configured, then do not initialize batch event queue
51
+ if SettingsService.instance.is_gateway_service_provided
52
+ LoggerService.log(LogLevelEnum::INFO, "GATEWAY_AND_BATCH_EVENTS_CONFIG_MISMATCH")
53
+ return self
54
+ end
55
+ begin
56
+ if @options.key?(:batch_event_data)
57
+ if @options[:batch_event_data].is_a?(Hash)
58
+ # Validate batch event parameters
59
+ events_per_request = @options[:batch_event_data][:events_per_request]
60
+ request_time_interval = @options[:batch_event_data][:request_time_interval]
61
+
62
+ if (!events_per_request.is_a?(Numeric) || events_per_request <= 0) &&
63
+ (!request_time_interval.is_a?(Numeric) || request_time_interval <= 0)
64
+ LoggerService.log(LogLevelEnum::ERROR, "INVALID_BATCH_EVENTS_CONFIG")
65
+ end
66
+
67
+ BatchEventsQueue.configure(
68
+ @options[:batch_event_data].merge(
69
+ {
70
+ account_id: @options[:account_id],
71
+ dispatcher: method(:dispatcher)
72
+ }
73
+ )
74
+ )
75
+ @batch_event_data = @options[:batch_event_data]
76
+ else
77
+ LoggerService.log(LogLevelEnum::ERROR, "Invalid batch events config, should be a hash.", nil)
78
+ end
79
+ end
80
+ rescue StandardError => e
81
+ LoggerService.log(LogLevelEnum::ERROR, "Failed to initialize batch event queue: #{e.message}", nil)
82
+ end
83
+ end
84
+
39
85
  # Set the network manager
40
86
  # @return [VWOBuilder] The VWOBuilder instance
41
87
  def set_network_manager
@@ -89,7 +135,12 @@ class VWOBuilder
89
135
  # Set the storage
90
136
  # @return [VWOBuilder] The VWOBuilder instance
91
137
  def set_storage
92
- @storage = @options[:storage] ? Storage.instance.attach_connector(@options[:storage]) : nil
138
+ if @options[:storage]
139
+ @storage = Storage.instance.attach_connector(@options[:storage])
140
+ Storage.instance.is_storage_enabled = true
141
+ else
142
+ @storage = nil
143
+ end
93
144
  LoggerService.log(LogLevelEnum::DEBUG, "SERVICE_INITIALIZED", {service: "Storage"})
94
145
  self
95
146
  end
@@ -116,26 +167,19 @@ class VWOBuilder
116
167
  # Initialize the polling
117
168
  # @return [VWOBuilder] The VWOBuilder instance
118
169
  def init_polling
119
- return self unless @options[:poll_interval]
120
-
121
- unless @options[:poll_interval].is_a?(Numeric)
122
- LoggerService.log(LogLevelEnum::ERROR, "INIT_OPTIONS_INVALID", {
123
- key: 'poll_interval',
124
- correctType: 'number'
125
- })
126
- return self
127
- end
128
-
129
- # Check if the polling interval is greater than or equal to 1000
130
- unless @options[:poll_interval] >= 1000
170
+ poll_interval = @options[:poll_interval]
171
+
172
+ if poll_interval && poll_interval.is_a?(Numeric) && poll_interval >= 1000
173
+ # this is to check if the poll_interval passed in options is valid
174
+ @is_valid_poll_interval_passed_from_init = true
175
+ check_and_poll
176
+ elsif poll_interval
177
+ # only log error if poll_interval is present in options
131
178
  LoggerService.log(LogLevelEnum::ERROR, "INIT_OPTIONS_INVALID", {
132
179
  key: 'poll_interval',
133
- correctType: 'number'
180
+ correctType: 'number >= 1000'
134
181
  })
135
- return self
136
182
  end
137
-
138
- check_and_poll
139
183
  self
140
184
  end
141
185
 
@@ -144,25 +188,42 @@ class VWOBuilder
144
188
  # @return [VWOClient] The VWO instance
145
189
  def build(settings)
146
190
  @vwo_instance = VWOClient.new(settings, @options)
191
+ # if poll_interval is not present in options, set it to the pollInterval from settings
192
+ update_poll_interval_and_check_and_poll(settings)
147
193
  @vwo_instance
148
194
  end
149
195
 
196
+ def update_poll_interval_and_check_and_poll(settings, should_check_and_poll = true)
197
+ # only update the poll_interval if it poll_interval is not valid or not present in options
198
+ if !@is_valid_poll_interval_passed_from_init
199
+ @options[:poll_interval] = settings["pollInterval"] || Constants::POLLING_INTERVAL
200
+ LoggerService.log(LogLevelEnum::DEBUG, "USING_POLL_INTERVAL_FROM_SETTINGS", {
201
+ source: settings["pollInterval"] ? 'settings' : 'default',
202
+ pollInterval: @options[:poll_interval]
203
+ })
204
+ end
205
+ # should_check_and_poll will be true only when we are updating the poll_interval first time from self.build method
206
+ # if we are updating the poll_interval already running polling, we don't need to check and poll again
207
+ if should_check_and_poll && !@is_valid_poll_interval_passed_from_init
208
+ check_and_poll
209
+ end
210
+ end
211
+
150
212
  # This method is used to check and poll the settings from the server
151
213
  # @return [VWOBuilder] The VWOBuilder instance
152
214
  def check_and_poll
153
- polling_interval = @options[:poll_interval]
154
-
155
215
  @thread_pool = NetworkManager.instance.get_client.get_thread_pool
156
216
  @thread_pool.post do
157
217
  loop do
158
- sleep(polling_interval / 1000.0)
218
+ sleep(@options[:poll_interval]/ 1000.0)
159
219
  begin
160
220
  latest_settings = fetch_settings(true)
161
- if latest_settings.to_json != @settings.to_json
221
+ if latest_settings && latest_settings.to_json != @settings.to_json
162
222
  @settings = latest_settings
163
223
  LoggerService.log(LogLevelEnum::INFO, "POLLING_SET_SETTINGS")
164
224
  @vwo_instance.update_settings(latest_settings.clone, false) if @vwo_instance
165
- else
225
+ update_poll_interval_and_check_and_poll(latest_settings, false)
226
+ elsif latest_settings
166
227
  LoggerService.log(LogLevelEnum::INFO, "POLLING_NO_CHANGE_IN_SETTINGS")
167
228
  end
168
229
  rescue StandardError => e
@@ -171,4 +232,26 @@ class VWOBuilder
171
232
  end
172
233
  end
173
234
  end
235
+
236
+ def dispatcher(events, callback)
237
+ BatchEventDispatcher.dispatch(
238
+ {
239
+ ev: events
240
+ },
241
+ callback,
242
+ {
243
+ a: @options[:account_id],
244
+ env: @options[:sdk_key]
245
+ }
246
+ )
247
+ end
248
+
249
+ # Initialize the usage stats
250
+ # @return [VWOBuilder] The VWOBuilder instance
251
+ def init_usage_stats
252
+ return self if @options[:is_usage_stats_disabled]
253
+
254
+ UsageStatsUtil.set_usage_stats(@options)
255
+ self
256
+ end
174
257
  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.
@@ -23,6 +23,7 @@ require_relative 'services/logger_service'
23
23
  require_relative 'enums/log_level_enum'
24
24
  require_relative 'utils/network_util'
25
25
  require_relative 'models/schemas/settings_schema_validation'
26
+ require_relative 'services/batch_event_queue'
26
27
 
27
28
  class VWOClient
28
29
  attr_accessor :settings, :original_settings
@@ -59,7 +60,7 @@ class VWOClient
59
60
  LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'feature_key', type: feature_key.class.name , correctType: 'String'})
60
61
  raise TypeError, 'feature_key should be a non-empty string'
61
62
  end
62
- unless SettingsSchema.new.is_settings_valid(@original_settings)
63
+ unless SettingsService.instance.is_settings_valid
63
64
  LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
64
65
  raise TypeError, 'Invalid Settings'
65
66
  end
@@ -100,7 +101,7 @@ class VWOClient
100
101
  LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'event_properties', type: event_properties.class.name, correctType: 'Hash'})
101
102
  raise TypeError, 'event_properties should be a hash'
102
103
  end
103
- unless SettingsSchema.new.is_settings_valid(@original_settings)
104
+ unless SettingsService.instance.is_settings_valid
104
105
  LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
105
106
  raise TypeError, 'Invalid Settings'
106
107
  end
@@ -139,7 +140,7 @@ class VWOClient
139
140
  LoggerService.log(LogLevelEnum::ERROR, "API_INVALID_PARAM", {apiName: api_name, key: 'context.id', type: context[:id].class.name, correctType: 'String'})
140
141
  raise TypeError, 'Invalid context, id should be a non-empty string'
141
142
  end
142
- unless SettingsSchema.new.is_settings_valid(@original_settings)
143
+ unless SettingsService.instance.is_settings_valid
143
144
  LoggerService.log(LogLevelEnum::ERROR, "API_SETTING_INVALID")
144
145
  raise TypeError, 'Invalid Settings'
145
146
  end
@@ -189,4 +190,22 @@ class VWOClient
189
190
  )
190
191
  end
191
192
  end
193
+
194
+ # Flushes the batch events queue
195
+ # @return [void]
196
+ def flush_events
197
+ api_name = 'flush_events'
198
+ begin
199
+ LoggerService.log(LogLevelEnum::DEBUG, "API_CALLED", {apiName: api_name})
200
+ if BatchEventsQueue.instance.nil?
201
+ LoggerService.log(LogLevelEnum::ERROR, "Batching is not enabled. Pass batch_event_data in the SDK configuration while invoking init API.", nil)
202
+ raise StandardError, "Batch events queue is not initialized"
203
+ end
204
+ # flush the batch events queue
205
+ @response = BatchEventsQueue.instance.flush(true)
206
+ @response
207
+ rescue StandardError => e
208
+ LoggerService.log(LogLevelEnum::ERROR, "API_THROW_ERROR", {apiName: api_name, err: e.message})
209
+ end
210
+ end
192
211
  end
data/lib/vwo.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.
@@ -36,6 +36,8 @@ class VWO
36
36
  .set_network_manager
37
37
  .set_segmentation
38
38
  .init_polling
39
+ .init_usage_stats
40
+ .init_batch
39
41
 
40
42
  if options[:settings]
41
43
  return @@vwo_builder.build(options[:settings])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vwo-fme-ruby-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-04-07 00:00:00.000000000 Z
11
+ date: 2025-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: uuidtools
@@ -161,6 +161,7 @@ files:
161
161
  - lib/vwo/enums/hooks_enum.rb
162
162
  - lib/vwo/enums/http_method_enum.rb
163
163
  - lib/vwo/enums/log_level_enum.rb
164
+ - lib/vwo/enums/log_level_to_number.rb
164
165
  - lib/vwo/enums/status_enum.rb
165
166
  - lib/vwo/enums/storage_enum.rb
166
167
  - lib/vwo/enums/url_enum.rb
@@ -200,11 +201,13 @@ files:
200
201
  - lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb
201
202
  - lib/vwo/packages/storage/connector.rb
202
203
  - lib/vwo/packages/storage/storage.rb
204
+ - lib/vwo/services/batch_event_queue.rb
203
205
  - lib/vwo/services/campaign_decision_service.rb
204
206
  - lib/vwo/services/hooks_service.rb
205
207
  - lib/vwo/services/logger_service.rb
206
208
  - lib/vwo/services/settings_service.rb
207
209
  - lib/vwo/services/storage_service.rb
210
+ - lib/vwo/utils/batch_event_dispatcher.rb
208
211
  - lib/vwo/utils/campaign_util.rb
209
212
  - lib/vwo/utils/data_type_util.rb
210
213
  - lib/vwo/utils/decision_util.rb
@@ -217,6 +220,7 @@ files:
217
220
  - lib/vwo/utils/rule_evaluation_util.rb
218
221
  - lib/vwo/utils/settings_util.rb
219
222
  - lib/vwo/utils/url_util.rb
223
+ - lib/vwo/utils/usage_stats_util.rb
220
224
  - lib/vwo/utils/uuid_util.rb
221
225
  - lib/vwo/vwo_builder.rb
222
226
  - lib/vwo/vwo_client.rb