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.
Files changed (80) 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/status_enum.rb +1 -1
  19. data/lib/vwo/enums/storage_enum.rb +1 -1
  20. data/lib/vwo/enums/url_enum.rb +2 -1
  21. data/lib/vwo/models/campaign/campaign_model.rb +1 -1
  22. data/lib/vwo/models/campaign/feature_model.rb +1 -1
  23. data/lib/vwo/models/campaign/impact_campaign_model.rb +1 -1
  24. data/lib/vwo/models/campaign/metric_model.rb +1 -1
  25. data/lib/vwo/models/campaign/rule_model.rb +1 -1
  26. data/lib/vwo/models/campaign/variable_model.rb +1 -1
  27. data/lib/vwo/models/campaign/variation_model.rb +1 -1
  28. data/lib/vwo/models/gateway_service_model.rb +1 -1
  29. data/lib/vwo/models/schemas/settings_schema_validation.rb +1 -1
  30. data/lib/vwo/models/settings/settings_model.rb +8 -2
  31. data/lib/vwo/models/storage/storage_data_model.rb +1 -1
  32. data/lib/vwo/models/user/context_model.rb +1 -1
  33. data/lib/vwo/models/user/context_vwo_model.rb +1 -1
  34. data/lib/vwo/models/user/get_flag_response.rb +1 -1
  35. data/lib/vwo/models/vwo_options_model.rb +1 -1
  36. data/lib/vwo/packages/decision_maker/decision_maker.rb +1 -1
  37. data/lib/vwo/packages/logger/core/log_manager.rb +1 -1
  38. data/lib/vwo/packages/logger/core/transport_manager.rb +1 -1
  39. data/lib/vwo/packages/logger/log_message_builder.rb +1 -1
  40. data/lib/vwo/packages/logger/logger.rb +1 -1
  41. data/lib/vwo/packages/logger/transports/console_transport.rb +1 -1
  42. data/lib/vwo/packages/network_layer/client/network_client.rb +39 -25
  43. data/lib/vwo/packages/network_layer/handlers/request_handler.rb +1 -1
  44. data/lib/vwo/packages/network_layer/manager/network_manager.rb +6 -4
  45. data/lib/vwo/packages/network_layer/models/global_request_model.rb +1 -1
  46. data/lib/vwo/packages/network_layer/models/request_model.rb +1 -1
  47. data/lib/vwo/packages/network_layer/models/response_model.rb +9 -1
  48. data/lib/vwo/packages/segmentation_evaluator/core/segmentation_manager.rb +1 -1
  49. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_regex_enum.rb +1 -1
  50. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operand_value_enum.rb +1 -1
  51. data/lib/vwo/packages/segmentation_evaluator/enums/segment_operator_value_enum.rb +1 -1
  52. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_evaluator.rb +1 -1
  53. data/lib/vwo/packages/segmentation_evaluator/evaluators/segment_operand_evaluator.rb +1 -1
  54. data/lib/vwo/packages/segmentation_evaluator/utils/segment_util.rb +1 -1
  55. data/lib/vwo/packages/storage/connector.rb +1 -1
  56. data/lib/vwo/packages/storage/storage.rb +3 -1
  57. data/lib/vwo/services/batch_event_queue.rb +179 -0
  58. data/lib/vwo/services/campaign_decision_service.rb +1 -1
  59. data/lib/vwo/services/hooks_service.rb +1 -1
  60. data/lib/vwo/services/logger_service.rb +1 -1
  61. data/lib/vwo/services/settings_service.rb +4 -2
  62. data/lib/vwo/services/storage_service.rb +1 -1
  63. data/lib/vwo/utils/batch_event_dispatcher.rb +117 -0
  64. data/lib/vwo/utils/campaign_util.rb +1 -1
  65. data/lib/vwo/utils/data_type_util.rb +1 -1
  66. data/lib/vwo/utils/decision_util.rb +1 -1
  67. data/lib/vwo/utils/function_util.rb +5 -1
  68. data/lib/vwo/utils/gateway_service_util.rb +1 -1
  69. data/lib/vwo/utils/impression_util.rb +10 -3
  70. data/lib/vwo/utils/log_message_util.rb +1 -1
  71. data/lib/vwo/utils/meg_util.rb +1 -1
  72. data/lib/vwo/utils/network_util.rb +16 -7
  73. data/lib/vwo/utils/rule_evaluation_util.rb +1 -1
  74. data/lib/vwo/utils/settings_util.rb +1 -1
  75. data/lib/vwo/utils/url_util.rb +1 -1
  76. data/lib/vwo/utils/uuid_util.rb +1 -1
  77. data/lib/vwo/vwo_builder.rb +97 -24
  78. data/lib/vwo/vwo_client.rb +23 -4
  79. data/lib/vwo.rb +2 -1
  80. metadata +4 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8e0d70f7fcb19c20548cdb55639655c0098f5fa149137014982baafb8bd185e9
4
- data.tar.gz: 54c0eab76aef36e5de32fc4953e3cea7add5bbed100d1777c08da18cff900b01
3
+ metadata.gz: 21c0e79e4c0cca26188c44b647de95c940bf919e4f88f584ef41836068f1cff2
4
+ data.tar.gz: 4ef7bda68a051cb7365d9607ba8d48e0dc82924a11cabaedbbb947db73b15999
5
5
  SHA512:
6
- metadata.gz: e78ca66f6fb6c71e60519658e04362c0b701d81ac3c79ecd18b8ad7aafedce4aec619dac425f1060b4c3f23aec55d43844645be69f998c4a280cd9a0ee70a9b7
7
- data.tar.gz: 543ed4464c0e6685a6fa695d5237a573f0553f29f39bd13476451f2ba6e2a4ea21bfe595c01b1aceb356c9ca159e1c739d2f9e33f2eefc3ce9afcb70283c04ab
6
+ metadata.gz: 0450c78a51f8a3fa8352c9b6fe66b6ec48b448187e7fcad33e501f6810d53d919b6d0ec9492a314d9885cb9a28568c0ffe1248e3742f99da8415f735622c2d60
7
+ data.tar.gz: d4aa3eca37dfbff8f035af7392d92851bbf239234f1bd933e7c7143ca0ebec5778d9e5e6159a11f9601c986ea6533331bc55013351a3a81ecc5f2b957587e674
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "API_CALLED": "API - {apiName} called",
3
3
  "SERVICE_INITIALIZED": "VWO {service} initialized while creating an instance of SDK",
4
+ "USING_POLL_INTERVAL_FROM_SETTINGS": "key: poll_interval not found or invalid. Using poll_interval from {source} ({pollInterval})",
4
5
 
5
6
  "EXPERIMENTS_EVALUATION_WHEN_ROLLOUT_PASSED": "Rollout rule got passed for user {userId}. Hence, evaluating experiments",
6
7
  "EXPERIMENTS_EVALUATION_WHEN_NO_ROLLOUT_PRESENT": "No Rollout rules present for the feature. Hence, checking experiment rules",
@@ -9,5 +10,11 @@
9
10
 
10
11
  "IMPRESSION_FOR_TRACK_USER": "Impression built for vwo_variationShown(VWO standard event for tracking user) event haivng Account ID:{accountId}, User ID:{userId}, and experiment ID:{campaignId}",
11
12
  "IMPRESSION_FOR_TRACK_GOAL": "Impression built for event:{eventName} event having Account ID:{accountId}, and user ID:{userId}",
12
- "IMPRESSION_FOR_SYNC_VISITOR_PROP": "Impression built for {eventName}(VWO internal event) event for Account ID:{accountId}, and user ID:{userId}"
13
+ "IMPRESSION_FOR_SYNC_VISITOR_PROP": "Impression built for {eventName}(VWO internal event) event for Account ID:{accountId}, and user ID:{userId}",
14
+
15
+ "CONFIG_BATCH_EVENT_LIMIT_EXCEEDED": "Impression event - {endPoint} failed due to exceeding payload size. Parameter eventsPerRequest in batchEvents config in init API has value:{eventsPerRequest} for account ID:{accountId}. Please read the official documentation for knowing the size limits",
16
+
17
+ "EVENT_BATCH_BEFORE_FLUSHING": "Flushing event queue {manually} having {length} events for Account ID:{accountId}. {timer}",
18
+ "EVENT_BATCH_FLUSH": "Manually flushing batch events for Account ID:{accountId} having {queueLength} events",
19
+ "BATCH_QUEUE_EMPTY": "Batch queue is empty. Nothing to flush."
13
20
  }
@@ -26,5 +26,9 @@
26
26
  "NETWORK_CALL_FAILED": "Error occurred while sending {method} request. Error:{err}",
27
27
  "SETTINGS_FETCH_FAILED": "Failed to fetch settings and hence VWO client instance couldn't be updated when API: {apiName} got called having isViaWebhook param as {isViaWebhook}. Error: {err}",
28
28
  "NETWORK_CALL_RETRY_ATTEMPT": "Request failed for {endPoint}, Error: {err}. Retrying in {delay} seconds, attempt {attempt} of {maxRetries}",
29
- "NETWORK_CALL_RETRY_FAILED": "Max retries reached. Request failed for {endPoint}, Error: {err}"
29
+ "NETWORK_CALL_RETRY_FAILED": "Max retries reached. Request failed for {endPoint}, Error: {err}",
30
+
31
+ "CONFIG_PARAMETER_INVALID": "{parameter} paased in {api} API is not correct. It should be of type:{type}}",
32
+ "BATCH_QUEUE_EMPTY": "No batch queue present for account:{accountId} when calling flushEvents API. Check batchEvents config in init API",
33
+ "INVALID_BATCH_EVENTS_CONFIG": "Invalid batch events config, should be a hash, events_per_request should be a number greater than 0 and request_time_interval should be a number greater than 0"
30
34
  }
@@ -29,5 +29,13 @@
29
29
  "MEG_CAMPAIGN_ELIGIBLE": "Campaign {campaignKey} is eligible for user ID:{userId}",
30
30
  "MEG_WINNER_CAMPAIGN": "MEG: Campaign {campaignKey} is the winner for group {groupId} for user ID:{userId} {algo}",
31
31
  "SETTINGS_UPDATED": "Settings fetched and updated successfully on the current VWO client instance when API: {apiName} got called having isViaWebhook param as {isViaWebhook}",
32
- "NETWORK_CALL_SUCCESS": "Impression for {event} - {endPoint} was successfully received by VWO having Account ID:{accountId}, User ID:{userId} and UUID: {uuid}"
32
+ "NETWORK_CALL_SUCCESS": "Impression for {event} - {endPoint} was successfully received by VWO having Account ID:{accountId}, User ID:{userId} and UUID: {uuid}",
33
+
34
+ "EVENT_BATCH_DEFAULTS": "{parameter} in SDK configuration is missing or invalid (should be greater than {minLimit}). Using default value: {defaultValue}",
35
+ "EVENT_QUEUE": "Event with payload:{event} pushed to the {queueType} queue",
36
+ "EVENT_BATCH_After_FLUSHING": "Event queue having {length} events has been flushed {manually}",
37
+ "IMPRESSION_BATCH_SUCCESS": "Impression event - {endPoint} was successfully received by VWO having Account ID:{accountId}",
38
+ "IMPRESSION_BATCH_FAILED": "Batch events couldn\"t be received by VWO. Calling Flush Callback with error and data",
39
+ "EVENT_BATCH_MAX_LIMIT": "{parameter} passed in SDK configuration is greater than the maximum limit of {maxLimit}. Setting it to the maximum limit",
40
+ "GATEWAY_AND_BATCH_EVENTS_CONFIG_MISMATCH": "Batch Events config passed in SDK configuration will not work as the gatewayService is already configured. Please check the documentation for more details"
33
41
  }
@@ -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.
@@ -26,6 +26,7 @@ require_relative '../utils/rule_evaluation_util'
26
26
  require_relative '../utils/impression_util'
27
27
  require_relative '../utils/decision_util'
28
28
  require_relative '../models/user/get_flag_response'
29
+ require_relative '../packages/storage/storage'
29
30
 
30
31
  class FlagApi
31
32
  # Get the flag for a given feature key and context
@@ -55,35 +56,37 @@ class FlagApi
55
56
  }
56
57
 
57
58
  storage_service = StorageService.new
58
- stored_data = StorageDecorator.new.get_feature_from_storage(feature_key, context, storage_service)
59
-
60
- if stored_data && stored_data[:experiment_variation_id]
61
- if stored_data[:experiment_key]
62
- variation = CampaignUtil.get_variation_from_campaign_key(settings, stored_data[:experiment_key], stored_data[:experiment_variation_id])
63
-
59
+ if Storage.instance.is_storage_enabled
60
+ stored_data = StorageDecorator.new.get_feature_from_storage(feature_key, context, storage_service)
61
+
62
+ if stored_data && stored_data[:experiment_variation_id]
63
+ if stored_data[:experiment_key]
64
+ variation = CampaignUtil.get_variation_from_campaign_key(settings, stored_data[:experiment_key], stored_data[:experiment_variation_id])
65
+
66
+ if variation
67
+ LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:experiment_key], experimentType: "experiment"})
68
+ return GetFlagResponse.new(true, variation.get_variables)
69
+ end
70
+ end
71
+ elsif stored_data && stored_data[:rollout_key] && stored_data[:rollout_id]
72
+ variation = CampaignUtil.get_variation_from_campaign_key(settings, stored_data[:rollout_key], stored_data[:rollout_variation_id])
73
+
64
74
  if variation
65
- LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:experiment_key], experimentType: "experiment"})
66
- return GetFlagResponse.new(true, variation.get_variables)
75
+ LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:rollout_key], experimentType: "rollout"})
76
+ LoggerService.log(LogLevelEnum::DEBUG, "EXPERIMENTS_EVALUATION_WHEN_ROLLOUT_PASSED", {userId: context.get_id})
77
+
78
+ is_enabled = true
79
+ should_check_for_experiments_rules = true
80
+ rollout_variation_to_return = variation
81
+ feature_info = {
82
+ rollout_id: stored_data[:rollout_id],
83
+ rollout_key: stored_data[:rollout_key],
84
+ rollout_variation_id: stored_data[:rollout_variation_id]
85
+ }
86
+ evaluated_feature_map[feature_key] = feature_info
87
+ passed_rules_information.merge!(feature_info)
67
88
  end
68
89
  end
69
- elsif stored_data && stored_data[:rollout_key] && stored_data[:rollout_id]
70
- variation = CampaignUtil.get_variation_from_campaign_key(settings, stored_data[:rollout_key], stored_data[:rollout_variation_id])
71
-
72
- if variation
73
- LoggerService.log(LogLevelEnum::INFO, "STORED_VARIATION_FOUND", {variationKey: variation.get_key, userId: context.get_id, experimentKey: stored_data[:rollout_key], experimentType: "rollout"})
74
- LoggerService.log(LogLevelEnum::DEBUG, "EXPERIMENTS_EVALUATION_WHEN_ROLLOUT_PASSED", {userId: context.get_id})
75
-
76
- is_enabled = true
77
- should_check_for_experiments_rules = true
78
- rollout_variation_to_return = variation
79
- feature_info = {
80
- rollout_id: stored_data[:rollout_id],
81
- rollout_key: stored_data[:rollout_key],
82
- rollout_variation_id: stored_data[:rollout_variation_id]
83
- }
84
- evaluated_feature_map[feature_key] = feature_info
85
- passed_rules_information.merge!(feature_info)
86
- end
87
90
  end
88
91
 
89
92
  if feature.nil?
@@ -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,6 +16,7 @@ require_relative '../models/user/context_model'
16
16
  require_relative '../enums/event_enum'
17
17
  require_relative '../utils/network_util'
18
18
  require_relative '../models/settings/settings_model'
19
+ require_relative '../services/batch_event_queue'
19
20
 
20
21
  class SetAttributeApi
21
22
  # Sets multiple attributes for a user in a single network call.
@@ -51,7 +52,13 @@ class SetAttributeApi
51
52
  context.ip_address
52
53
  )
53
54
 
54
- # Send the constructed payload via POST request
55
- NetworkUtil.send_post_api_request(properties, payload)
55
+ # check if batching is enabled
56
+ if BatchEventsQueue.instance
57
+ # add the payload to the batch events queue
58
+ BatchEventsQueue.instance.enqueue(payload)
59
+ else
60
+ # Send the constructed payload via POST request
61
+ NetworkUtil.send_post_api_request(properties, payload)
62
+ end
56
63
  end
57
64
  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.
@@ -19,6 +19,8 @@ require_relative '../services/hooks_service'
19
19
  require_relative '../utils/function_util'
20
20
  require_relative '../utils/network_util'
21
21
  require_relative '../services/logger_service'
22
+ require_relative '../services/batch_event_queue'
23
+
22
24
  class TrackApi
23
25
  # Tracks an event with given properties and context.
24
26
  # @param settings [SettingsModel] Configuration settings.
@@ -71,7 +73,13 @@ class TrackApi
71
73
  context.ip_address
72
74
  )
73
75
 
74
- # Send the prepared payload via POST API request
75
- NetworkUtil.send_post_api_request(properties, payload)
76
+ # check if batching is enabled
77
+ if BatchEventsQueue.instance
78
+ # add the payload to the batch events queue
79
+ BatchEventsQueue.instance.enqueue(payload)
80
+ else
81
+ # Send the prepared payload via POST API request
82
+ NetworkUtil.send_post_api_request(properties, payload)
83
+ end
76
84
  end
77
85
  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,7 +17,7 @@
17
17
  # Define the Constants module
18
18
  module Constants
19
19
  SDK_NAME = 'vwo-fme-ruby-sdk'.freeze
20
- SDK_VERSION = '1.2.0'.freeze
20
+ SDK_VERSION = '1.3.0'.freeze
21
21
 
22
22
  MAX_TRAFFIC_PERCENT = 100
23
23
  MAX_TRAFFIC_VALUE = 10_000
@@ -27,6 +27,8 @@ module Constants
27
27
  MAX_EVENTS_PER_REQUEST = 5_000
28
28
  DEFAULT_REQUEST_TIME_INTERVAL = 600 # 10 minutes in seconds
29
29
  DEFAULT_EVENTS_PER_REQUEST = 100
30
+ MIN_REQUEST_TIME_INTERVAL = 2
31
+ MIN_EVENTS_PER_REQUEST = 1
30
32
 
31
33
  SEED_URL = 'https://vwo.com'.freeze # Define SEED_URL
32
34
  HTTP_PROTOCOL = 'http'.freeze
@@ -35,6 +37,7 @@ module Constants
35
37
  SETTINGS = 'settings'.freeze
36
38
  SETTINGS_EXPIRY = 10_000_000
37
39
  SETTINGS_TIMEOUT = 50_000
40
+ POLLING_INTERVAL = 600_000 # 10 minutes in milliseconds
38
41
 
39
42
  HOST_NAME = 'dev.visualwebsiteoptimizer.com'.freeze
40
43
  SETTINGS_ENDPOINT = '/server-side/v2-settings'.freeze
@@ -51,4 +54,5 @@ module Constants
51
54
 
52
55
  SHOULD_USE_THREADING = true
53
56
  MAX_POOL_SIZE = 5
57
+ MAX_QUEUE_SIZE = 10000
54
58
  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.
@@ -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.
@@ -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.
@@ -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.
@@ -18,4 +18,5 @@ module UrlEnum
18
18
  EVENTS = '/events/t'
19
19
  ATTRIBUTE_CHECK = '/check-attribute'
20
20
  GET_USER_DATA = '/get-user-details'
21
+ BATCH_EVENTS = '/server-side/batch-events-v2'
21
22
  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.
@@ -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.
@@ -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.
@@ -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.
@@ -14,16 +14,18 @@
14
14
 
15
15
  require_relative '../campaign/campaign_model'
16
16
  require_relative '../campaign/feature_model'
17
+ require_relative '../../constants/constants'
17
18
 
18
19
  class SettingsModel
19
20
  attr_reader :sdk_key, :account_id, :version, :collection_prefix,
20
- :features, :campaigns, :campaign_groups, :groups
21
+ :features, :campaigns, :campaign_groups, :groups, :poll_interval
21
22
 
22
23
  def initialize(settings)
23
24
  @sdk_key = settings["sdkKey"]
24
25
  @account_id = settings["accountId"]
25
26
  @version = settings["version"]
26
27
  @collection_prefix = settings["collectionPrefix"]
28
+ @poll_interval = settings["pollInterval"] || Constants::POLLING_INTERVAL
27
29
  @features = []
28
30
  @campaigns = []
29
31
  @campaign_groups = settings["campaignGroups"] || {}
@@ -65,6 +67,10 @@ class SettingsModel
65
67
  @collection_prefix
66
68
  end
67
69
 
70
+ def get_poll_interval
71
+ @poll_interval
72
+ end
73
+
68
74
  def process_features(settings)
69
75
  feature_list = settings["features"]
70
76
  return unless feature_list.is_a?(Array)
@@ -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.
@@ -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.
@@ -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.
@@ -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.
@@ -27,13 +27,26 @@ class NetworkClient
27
27
  def initialize(options = {})
28
28
  # options for threading
29
29
  @should_use_threading = options.key?(:enabled) ? options[:enabled] : Constants::SHOULD_USE_THREADING
30
- @thread_pool = Concurrent::FixedThreadPool.new(options.key?(:max_pool_size) ? options[:max_pool_size] : Constants::MAX_POOL_SIZE)
30
+ @thread_pool = Concurrent::ThreadPoolExecutor.new(
31
+ # Minimum number of threads to keep alive in the pool
32
+ min_threads: 1,
33
+ # Maximum number of threads allowed in the pool, configurable via options or defaults to MAX_POOL_SIZE constant
34
+ max_threads: options.key?(:max_pool_size) ? options[:max_pool_size] : Constants::MAX_POOL_SIZE,
35
+ # Maximum number of tasks that can be queued when all threads are busy
36
+ max_queue: options.key?(:max_queue_size) ? options[:max_queue_size] : Constants::MAX_QUEUE_SIZE,
37
+ # When queue is full, execute task in the caller's thread rather than rejecting it
38
+ fallback_policy: :caller_runs
39
+ )
31
40
  end
32
41
 
33
42
  def get_thread_pool
34
43
  @thread_pool
35
44
  end
36
45
 
46
+ def get_should_use_threading
47
+ @should_use_threading
48
+ end
49
+
37
50
  def get(request_model)
38
51
  # Build the URL and headers
39
52
  url = request_model.get_url + request_model.get_path
@@ -67,22 +80,24 @@ class NetworkClient
67
80
  end
68
81
 
69
82
  def post(request_model)
70
- def execute_post(request_model)
71
- url = request_model.get_url + request_model.get_path
72
- uri = URI(url)
73
- headers = request_model.get_headers # Directly use the hash from the request model
74
- body = JSON.dump(request_model.get_body)
75
-
76
- request = Net::HTTP::Post.new(uri, headers) # Pass the hash of headers directly
77
- request.body = body
78
-
79
- response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(request) }
80
-
81
- response_model = ResponseModel.new
82
- response_model.set_status_code(response.code.to_i)
83
+ url = request_model.get_url + request_model.get_path
84
+ uri = URI(url)
85
+ headers = request_model.get_headers
86
+ body = JSON.dump(request_model.get_body)
87
+
88
+ request = Net::HTTP::Post.new(uri, headers)
89
+ request.body = body
83
90
 
84
- # Check if the response body is empty or invalid before parsing
85
- if response.is_a?(Net::HTTPSuccess) && !response.body.strip.empty?
91
+ response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: uri.scheme == 'https') { |http| http.request(request) }
92
+
93
+ response_model = ResponseModel.new
94
+ response_model.set_status_code(response.code.to_i)
95
+
96
+ # Check if the response body is empty or invalid before parsing
97
+ if response.is_a?(Net::HTTPSuccess) && !response.body.strip.empty?
98
+ # Check if the response body is JSON
99
+ content_type = response['Content-Type']&.downcase
100
+ if content_type&.include?('application/json')
86
101
  begin
87
102
  parsed_data = JSON.parse(response.body)
88
103
  response_model.set_data(parsed_data)
@@ -91,17 +106,16 @@ class NetworkClient
91
106
  response_model.set_error("Invalid JSON response: #{e.message}")
92
107
  end
93
108
  else
109
+ response_model.set_data(response.body)
94
110
  end
95
- rescue StandardError => e
96
- LoggerService.log(LogLevelEnum::ERROR, "POST request failed: #{e.message}", nil)
97
111
  end
98
112
 
99
- # Check if threading is enabled in options
100
- if @should_use_threading
101
- @thread_pool.post { execute_post(request_model) }
102
- else
103
- execute_post(request_model)
104
- end
113
+ response_model
114
+ rescue StandardError => e
115
+ LoggerService.log(LogLevelEnum::ERROR, "POST request failed: #{e.message}", nil)
116
+ response_model = ResponseModel.new
117
+ response_model.set_error(e.message)
118
+ response_model
105
119
  end
106
120
 
107
121
  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.