splitclient-rb 6.4.1 → 7.0.0.pre.rc1

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 (67) hide show
  1. checksums.yaml +4 -4
  2. data/Detailed-README.md +9 -21
  3. data/lib/splitclient-rb/cache/adapters/cache_adapter.rb +3 -3
  4. data/lib/splitclient-rb/cache/repositories/events/memory_repository.rb +5 -4
  5. data/lib/splitclient-rb/cache/repositories/events/redis_repository.rb +4 -3
  6. data/lib/splitclient-rb/cache/repositories/events_repository.rb +10 -9
  7. data/lib/splitclient-rb/cache/repositories/impressions/memory_repository.rb +7 -6
  8. data/lib/splitclient-rb/cache/repositories/impressions/redis_repository.rb +5 -4
  9. data/lib/splitclient-rb/cache/repositories/impressions_repository.rb +9 -8
  10. data/lib/splitclient-rb/cache/repositories/metrics/memory_repository.rb +3 -2
  11. data/lib/splitclient-rb/cache/repositories/metrics/redis_repository.rb +5 -4
  12. data/lib/splitclient-rb/cache/repositories/metrics_repository.rb +6 -4
  13. data/lib/splitclient-rb/cache/repositories/repository.rb +7 -2
  14. data/lib/splitclient-rb/cache/repositories/segments_repository.rb +6 -5
  15. data/lib/splitclient-rb/cache/repositories/splits_repository.rb +54 -7
  16. data/lib/splitclient-rb/cache/routers/impression_router.rb +5 -4
  17. data/lib/splitclient-rb/cache/senders/events_sender.rb +7 -6
  18. data/lib/splitclient-rb/cache/senders/impressions_sender.rb +10 -9
  19. data/lib/splitclient-rb/cache/senders/metrics_sender.rb +9 -8
  20. data/lib/splitclient-rb/cache/stores/sdk_blocker.rb +19 -10
  21. data/lib/splitclient-rb/cache/stores/segment_store.rb +15 -28
  22. data/lib/splitclient-rb/cache/stores/split_store.rb +13 -15
  23. data/lib/splitclient-rb/clients/localhost_split_client.rb +8 -7
  24. data/lib/splitclient-rb/clients/split_client.rb +65 -35
  25. data/lib/splitclient-rb/engine/api/client.rb +17 -13
  26. data/lib/splitclient-rb/engine/api/events.rb +7 -6
  27. data/lib/splitclient-rb/engine/api/impressions.rb +6 -5
  28. data/lib/splitclient-rb/engine/api/metrics.rb +8 -7
  29. data/lib/splitclient-rb/engine/api/segments.rb +11 -10
  30. data/lib/splitclient-rb/engine/api/splits.rb +6 -5
  31. data/lib/splitclient-rb/engine/matchers/all_keys_matcher.rb +1 -1
  32. data/lib/splitclient-rb/engine/matchers/between_matcher.rb +7 -5
  33. data/lib/splitclient-rb/engine/matchers/combining_matcher.rb +5 -4
  34. data/lib/splitclient-rb/engine/matchers/contains_all_matcher.rb +4 -4
  35. data/lib/splitclient-rb/engine/matchers/contains_any_matcher.rb +3 -3
  36. data/lib/splitclient-rb/engine/matchers/contains_matcher.rb +7 -5
  37. data/lib/splitclient-rb/engine/matchers/dependency_matcher.rb +3 -2
  38. data/lib/splitclient-rb/engine/matchers/ends_with_matcher.rb +5 -4
  39. data/lib/splitclient-rb/engine/matchers/equal_to_boolean_matcher.rb +3 -2
  40. data/lib/splitclient-rb/engine/matchers/equal_to_matcher.rb +6 -4
  41. data/lib/splitclient-rb/engine/matchers/equal_to_set_matcher.rb +3 -3
  42. data/lib/splitclient-rb/engine/matchers/greater_than_or_equal_to_matcher.rb +6 -4
  43. data/lib/splitclient-rb/engine/matchers/less_than_or_equal_to_matcher.rb +6 -4
  44. data/lib/splitclient-rb/engine/matchers/matcher.rb +4 -0
  45. data/lib/splitclient-rb/engine/matchers/matches_string_matcher.rb +3 -2
  46. data/lib/splitclient-rb/engine/matchers/negation_matcher.rb +3 -2
  47. data/lib/splitclient-rb/engine/matchers/part_of_set_matcher.rb +4 -4
  48. data/lib/splitclient-rb/engine/matchers/set_matcher.rb +2 -1
  49. data/lib/splitclient-rb/engine/matchers/starts_with_matcher.rb +4 -3
  50. data/lib/splitclient-rb/engine/matchers/user_defined_segment_matcher.rb +3 -2
  51. data/lib/splitclient-rb/engine/matchers/whitelist_matcher.rb +7 -5
  52. data/lib/splitclient-rb/engine/models/label.rb +2 -0
  53. data/lib/splitclient-rb/engine/parser/condition.rb +31 -20
  54. data/lib/splitclient-rb/engine/parser/evaluator.rb +3 -2
  55. data/lib/splitclient-rb/engine/parser/split_adapter.rb +9 -7
  56. data/lib/splitclient-rb/localhost_split_factory.rb +3 -2
  57. data/lib/splitclient-rb/managers/split_manager.rb +39 -5
  58. data/lib/splitclient-rb/redis_metrics_fixer.rb +5 -4
  59. data/lib/splitclient-rb/split_config.rb +35 -14
  60. data/lib/splitclient-rb/split_factory.rb +44 -32
  61. data/lib/splitclient-rb/split_factory_builder.rb +4 -5
  62. data/lib/splitclient-rb/split_factory_registry.rb +51 -0
  63. data/lib/splitclient-rb/split_logger.rb +5 -14
  64. data/lib/splitclient-rb/validators.rb +19 -16
  65. data/lib/splitclient-rb/version.rb +1 -1
  66. data/lib/splitclient-rb.rb +2 -1
  67. metadata +5 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e5f0cb1310db3de8dbd8fdbeb006d301316e0075458d57894e3c8bf7113852ff
4
- data.tar.gz: f0fad2217853779af316ea7377b01756f78358ec2a6d0c27a20cb30a03f59903
3
+ metadata.gz: ab29a684d528253604fae421698aa7f1d6cc9278b0d3ff452a65f09ed7256933
4
+ data.tar.gz: ef8a2d7933a0a2d06e9d919f879ea28f05cf72b013d2567624525db5eee0de8f
5
5
  SHA512:
6
- metadata.gz: 6c6ee292131789437f3beaad4bed926f86c8898534b49c4c59846dfa491cf3eb8f79ea7d81ad95c4bdc8409f30a1eca99f466ea8a9d8b71f986ac52a4acc8b46
7
- data.tar.gz: 50857be3f98b7ae92030e69c8dc13a5908390097894028653112c6e9c9166b7349dc3f67196a77e33a504c0a5fadebad415181888bbbd0542f776c18a2d1fd92
6
+ metadata.gz: 7ca86c6d4bbd397b48bdaba4db5f7a33ef85ffd83a41b8ecc71f0b2d710d7c1e80d489c18b1c71664d8cf1f7df0805f4020919775e583ec36a1d2f89ba09a279
7
+ data.tar.gz: f465d07403dc3313fdc4a75dddc5c1a33b5840e2aabb4b95b598ce1f7a9ed0c0dd38a6a0e7031ae300a1f84c04281c7cd0a86af353439e655443859fb2ac2602
data/Detailed-README.md CHANGED
@@ -72,15 +72,12 @@ else
72
72
  end
73
73
  ```
74
74
 
75
- **Note**: You can ensure the SDK resources are loaded before querying for treatments by using `block_until_ready`. See [Advanced Configuration](#advanced-configuration).
76
- ``` ruby
77
- options = {
78
- block_until_ready: 10
79
- }
75
+ **Note**: You can ensure the SDK resources are loaded before querying for treatments by using `block_until_ready`.
80
76
 
81
- # Then init the factory passing the options hash
82
- factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY', options)
77
+ ``` ruby
78
+ factory = SplitIoClient::SplitFactoryBuilder.build('YOUR_API_KEY')
83
79
  split_client = factory.client
80
+ split_client.block_until_ready # Wait for a specified time (default 15 seconds). SDK raises an SDKBlockerTimeoutExpiredException if not ready by then
84
81
  ```
85
82
 
86
83
  For features that use targeting rules based on user attributes, you can call the `get_treatment` method the following way:
@@ -108,8 +105,6 @@ An scenario that requires the usage of both keys is a visitor user that browses
108
105
 
109
106
  Split solves this situation by introducing the concept of a matching_key and a bucketing key. By providing the `subscriber_id` as the `matching_key` and the `visitor_id` as the `bucketing_key`, Split will give the same treatment back to the user that it used to give to the visitor.
110
107
 
111
- **Note**: read more about this topic [here](https://docs.split.io/docs/anonymous-to-logged-in).
112
-
113
108
  The `bucketing_key` may be `nil`. In that case the `matching_key` would be used instead, so calling:
114
109
  ```ruby
115
110
  split_client.get_treatment(
@@ -174,6 +169,8 @@ Which would produce an output similar to:
174
169
  ]
175
170
  ```
176
171
 
172
+ **Note**: `block_until_ready` is also available as a Split manager method
173
+
177
174
  #### Localhost Mode
178
175
 
179
176
  You can run the SDK in _localhost_ mode. In this mode, the SDK won't actually communicate with the Split API, but it'll rather return treatments based on a `.split` file on your local environment. This file must be a list of `split_name treatment_name_to_be_returned` entries. e.g.:
@@ -216,7 +213,7 @@ In order to provide consistency among the SDKs for the different programming lan
216
213
 
217
214
  - `matching_key`, `bucketing_key`: the containing `Hash` must have both keys, and the same rules above apply for each.
218
215
 
219
- - `split_name`: must be a non-empty `String` or a `Symbol`. Whitespaces will be trimmed from both ends of it. The trimmed version of the `split_name` will be used for both evaluation and to store the resulting impression.
216
+ - `split_name`: must be a non-empty `String` or a `Symbol`. Whitespaces will be trimmed from both ends of it. The trimmed version of the `split_name` will be used for both evaluation and to store the resulting impression. In addition, split must exist in the environment.
220
217
 
221
218
  - `attributes`: must be of type `Hash`.
222
219
 
@@ -238,15 +235,12 @@ In order to provide consistency among the SDKs for the different programming lan
238
235
 
239
236
  #### split (split_manager)
240
237
 
241
- - `split_name`: must be a non-empty `String` or a `Symbol`.
238
+ - `split_name`: must be a non-empty `String` or a `Symbol`. In addition, split must exist in the environment.
242
239
 
243
240
  #### Configuration Parameters
244
241
 
245
242
  - `api_key`: must be a non-empty `String` or a `Symbol` of type `sdk` (`browser` type API keys will break this rule).
246
243
 
247
- - `block_until_ready`: a warning log message will be issued if this value is not set.
248
-
249
-
250
244
  #### Client Destroyed Rules
251
245
  Calls to the SDK methods are still possible after `destroy` is called. All will log an error message stating _client has been destroyed_.
252
246
 
@@ -329,12 +323,6 @@ The following values can be customized:
329
323
 
330
324
  *default value* = (no impression listener)
331
325
 
332
- **block_until_ready** : The SDK will block your app for the provided amount of seconds until it's ready. A `SplitIoClient::SDKBlockerTimeoutExpiredException` will be thrown If the provided time expires. When `0` is provided, the SDK runs in non-blocking mode.
333
-
334
- _When using consumer mode, blocking has no effect._
335
-
336
- *default value* = `0`
337
-
338
326
  **labels_enabled** : Allows preventing labels from being sent to the Split servers, as they may contain sensitive information.
339
327
 
340
328
  *default value* = `true`
@@ -448,7 +436,7 @@ In the example above, the listener simply takes an impression and logs it to the
448
436
  The SDK is capable of running in two different modes to fit in different infrastructure configurations:
449
437
 
450
438
  - `:standalone` - (default) : The SDK will retrieve information (e.g. split definitions) periodically from the Split servers, and store it in the memory cache. It'll also store the application execution information (e.g. impressions) in the cache and send it periodically to the Split servers. As it name implies, in this mode, the SDK neither relies nor synchronizes with any other component. _This mode is only available when using the `memory` cache adapter._
451
- - `:consumer` - If using a load balancer or more than one SDK in your application, guaranteeing that all changes in split definitions are picked up by all SDK instances at the same time is highly recommended in order to ensure consistent results across your infrastructure (i.e. getting the same treatment for a specific split and user pair). To achieve this, use the [Split Synchronizer](https://docs.split.io/docs/split-synchronizer)) and setup your SDKs to work in the `consumer` mode. Setting the components this way, all communication with the Split server is orchestrated by the Synchronizer, while the SDKs pick up definitions and store the execution information from / into a shared Redis data store. _This mode is only available when using the `redis` cache adapter._
439
+ - `:consumer` - If using a load balancer or more than one SDK in your application, guaranteeing that all changes in split definitions are picked up by all SDK instances at the same time is highly recommended in order to ensure consistent results across your infrastructure (i.e. getting the same treatment for a specific split and user pair). To achieve this, use the [Split Synchronizer](https://docs.split.io/docs/split-synchronizer)) and setup your SDKs to work in the `consumer` mode. Setting the components this way, all communication with the Split server is orchestrated by the Synchronizer, while the SDKs pick up definitions and store the execution information from / into a shared Redis data store. _This mode is only available when using the `redis` cache adapter. In addition, note that `block_until_ready` has no effect in this mode_
452
440
 
453
441
  _You can choose between these 2 modes setting the `mode` option in the config. An invalid combination of `cache_adaper` and `mode` will result in an Invalid Mode exception being raised._
454
442
 
@@ -7,9 +7,9 @@ module SplitIoClient
7
7
  extend Forwardable
8
8
  def_delegators :@adapter, :initialize_set, :set_bool, :pipelined
9
9
 
10
- def initialize(adapter)
11
- @cache = LruRedux::TTL::ThreadSafeCache.new(SplitIoClient.configuration.max_cache_size, SplitIoClient.configuration.cache_ttl)
12
- @adapter = adapter
10
+ def initialize(config)
11
+ @cache = LruRedux::TTL::ThreadSafeCache.new(config.max_cache_size, config.cache_ttl)
12
+ @adapter = config.cache_adapter
13
13
  end
14
14
 
15
15
  def delete(key)
@@ -5,8 +5,9 @@ module SplitIoClient
5
5
  class MemoryRepository < EventsRepository
6
6
  EVENTS_MAX_SIZE_BYTES = 5242880
7
7
 
8
- def initialize(adapter)
9
- @adapter = adapter
8
+ def initialize(config)
9
+ @config = config
10
+ @adapter = @config.events_adapter
10
11
  @size = 0
11
12
  end
12
13
 
@@ -14,10 +15,10 @@ module SplitIoClient
14
15
  @adapter.add_to_queue(m: metadata, e: event(key, traffic_type, event_type, time, value, properties))
15
16
  @size += event_size
16
17
 
17
- post_events if @size >= EVENTS_MAX_SIZE_BYTES || @adapter.length == SplitIoClient.configuration.events_queue_size
18
+ post_events if @size >= EVENTS_MAX_SIZE_BYTES || @adapter.length == @config.events_queue_size
18
19
 
19
20
  rescue StandardError => error
20
- SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
21
+ @config.log_found_exception(__method__.to_s, error)
21
22
  end
22
23
 
23
24
  def clear
@@ -4,8 +4,9 @@ module SplitIoClient
4
4
  module Events
5
5
  class RedisRepository < EventsRepository
6
6
 
7
- def initialize(adapter)
8
- @adapter = adapter
7
+ def initialize(config)
8
+ @config = config
9
+ @adapter = @config.events_adapter
9
10
  end
10
11
 
11
12
  def add(key, traffic_type, event_type, time, value, properties, size)
@@ -20,7 +21,7 @@ module SplitIoClient
20
21
  JSON.parse(e, symbolize_names: true)
21
22
  end
22
23
  rescue StandardError => e
23
- SplitIoClient.configuration.logger.error("Exception while clearing events cache: #{e}")
24
+ @config.logger.error("Exception while clearing events cache: #{e}")
24
25
  []
25
26
  end
26
27
  end
@@ -6,12 +6,13 @@ module SplitIoClient
6
6
  extend Forwardable
7
7
  def_delegators :@repository, :add, :clear
8
8
 
9
- def initialize(adapter, api_key)
10
- @repository = case adapter.class.to_s
9
+ def initialize(config, api_key)
10
+ super(config)
11
+ @repository = case @config.events_adapter.class.to_s
11
12
  when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
12
- Repositories::Events::MemoryRepository.new(adapter)
13
+ Repositories::Events::MemoryRepository.new(@config)
13
14
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
14
- Repositories::Events::RedisRepository.new(adapter)
15
+ Repositories::Events::RedisRepository.new(@config)
15
16
  end
16
17
 
17
18
  @api_key = api_key
@@ -20,16 +21,16 @@ module SplitIoClient
20
21
  def post_events
21
22
  events_api.post(self.clear)
22
23
  rescue StandardError => error
23
- SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
24
+ @config.log_found_exception(__method__.to_s, error)
24
25
  end
25
26
 
26
27
  protected
27
28
 
28
29
  def metadata
29
30
  {
30
- s: "#{SplitIoClient.configuration.language}-#{SplitIoClient.configuration.version}",
31
- i: SplitIoClient.configuration.machine_ip,
32
- n: SplitIoClient.configuration.machine_name
31
+ s: "#{@config.language}-#{@config.version}",
32
+ i: @config.machine_ip,
33
+ n: @config.machine_name
33
34
  }
34
35
  end
35
36
 
@@ -47,7 +48,7 @@ module SplitIoClient
47
48
  private
48
49
 
49
50
  def events_api
50
- @events_api ||= SplitIoClient::Api::Events.new(@api_key)
51
+ @events_api ||= SplitIoClient::Api::Events.new(@api_key, @config)
51
52
  end
52
53
  end
53
54
  end
@@ -5,8 +5,9 @@ module SplitIoClient
5
5
  module Repositories
6
6
  module Impressions
7
7
  class MemoryRepository < ImpressionsRepository
8
- def initialize(adapter)
9
- @adapter = adapter
8
+ def initialize(config)
9
+ @config = config
10
+ @adapter = @config.impressions_adapter
10
11
  end
11
12
 
12
13
  # Store impression data in the selected adapter
@@ -23,8 +24,8 @@ module SplitIoClient
23
24
  )
24
25
  rescue ThreadError # queue is full
25
26
  if random_sampler.rand(1..1000) <= 2 # log only 0.2 % of the time
26
- SplitIoClient.configuration.logger.warn("Dropping impressions. Current size is \
27
- #{SplitIoClient.configuration.impressions_queue_size}. " \
27
+ @config.logger.warn("Dropping impressions. Current size is \
28
+ #{@config.impressions_queue_size}. " \
28
29
  'Consider increasing impressions_queue_size')
29
30
  end
30
31
  end
@@ -36,9 +37,9 @@ module SplitIoClient
36
37
  end
37
38
 
38
39
  def batch
39
- return [] if SplitIoClient.configuration.impressions_bulk_size.zero?
40
+ return [] if @config.impressions_bulk_size.zero?
40
41
 
41
- @adapter.get_batch(SplitIoClient.configuration.impressions_bulk_size)
42
+ @adapter.get_batch(@config.impressions_bulk_size)
42
43
  end
43
44
 
44
45
  def clear
@@ -7,8 +7,9 @@ module SplitIoClient
7
7
  class RedisRepository < ImpressionsRepository
8
8
  EXPIRE_SECONDS = 3600
9
9
 
10
- def initialize(adapter)
11
- @adapter = adapter
10
+ def initialize(config)
11
+ @config = config
12
+ @adapter = @config.impressions_adapter
12
13
  end
13
14
 
14
15
  def add(matching_key, bucketing_key, split_name, treatment, time)
@@ -42,12 +43,12 @@ module SplitIoClient
42
43
  impression
43
44
  end
44
45
  rescue StandardError => e
45
- SplitIoClient.configuration.logger.error("Exception while clearing impressions cache: #{e}")
46
+ @config.logger.error("Exception while clearing impressions cache: #{e}")
46
47
  []
47
48
  end
48
49
 
49
50
  def batch
50
- get_impressions(SplitIoClient.configuration.impressions_bulk_size)
51
+ get_impressions(@config.impressions_bulk_size)
51
52
  end
52
53
 
53
54
  def clear
@@ -8,12 +8,13 @@ module SplitIoClient
8
8
  extend Forwardable
9
9
  def_delegators :@adapter, :add, :add_bulk, :batch, :clear, :empty?
10
10
 
11
- def initialize(adapter)
12
- @adapter = case adapter.class.to_s
11
+ def initialize(config)
12
+ super(config)
13
+ @adapter = case @config.impressions_adapter.class.to_s
13
14
  when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
14
- Repositories::Impressions::MemoryRepository.new(adapter)
15
+ Repositories::Impressions::MemoryRepository.new(@config)
15
16
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
16
- Repositories::Impressions::RedisRepository.new(adapter)
17
+ Repositories::Impressions::RedisRepository.new(@config)
17
18
  end
18
19
  end
19
20
 
@@ -33,14 +34,14 @@ module SplitIoClient
33
34
 
34
35
  def metadata
35
36
  {
36
- s: "#{SplitIoClient.configuration.language}-#{SplitIoClient.configuration.version}",
37
- i: SplitIoClient.configuration.machine_ip,
38
- n: SplitIoClient.configuration.machine_name
37
+ s: "#{@config.language}-#{@config.version}",
38
+ i: @config.machine_ip,
39
+ n: @config.machine_name
39
40
  }
40
41
  end
41
42
 
42
43
  def applied_rule(label)
43
- SplitIoClient.configuration.labels_enabled ? label : nil
44
+ @config.labels_enabled ? label : nil
44
45
  end
45
46
  end
46
47
  end
@@ -5,10 +5,11 @@ module SplitIoClient
5
5
  class MemoryRepository
6
6
  OPERATIONS = %w(sdk.get_treatment sdk.get_treatments sdk.get_treatment_with_config sdk.get_treatments_with_config)
7
7
 
8
- def initialize(_ = nil, adapter)
8
+ def initialize(_ = nil, config)
9
9
  @counts = []
10
10
  @latencies = []
11
11
  @gauges = []
12
+ @config = config
12
13
  end
13
14
 
14
15
  def add_count(counter, delta)
@@ -127,7 +128,7 @@ module SplitIoClient
127
128
  end
128
129
 
129
130
  private
130
-
131
+
131
132
  def increase_latency_bucket(operation, index)
132
133
  operation_latencies = find_operation_latencies(operation)
133
134
 
@@ -3,8 +3,9 @@ module SplitIoClient
3
3
  module Repositories
4
4
  module Metrics
5
5
  class RedisRepository < Repository
6
- def initialize(adapter = nil)
7
- @adapter = adapter
6
+ def initialize(config)
7
+ @config = config
8
+ @adapter = config.metrics_adapter
8
9
  end
9
10
 
10
11
  def add_count(counter, delta)
@@ -78,7 +79,7 @@ module SplitIoClient
78
79
 
79
80
  keys.concat @adapter.find_strings_by_pattern(latencies_to_be_deleted_key_pattern_prefix('*.time'))
80
81
 
81
- SplitIoClient.configuration.logger.info("Found incorrect latency keys, deleting. Keys: #{keys}") unless keys.size == 0
82
+ @config.logger.info("Found incorrect latency keys, deleting. Keys: #{keys}") unless keys.size == 0
82
83
 
83
84
  keys.each_slice(500) do |chunk|
84
85
  @adapter.pipelined do
@@ -90,7 +91,7 @@ module SplitIoClient
90
91
  end
91
92
 
92
93
  def latencies_to_be_deleted_key_pattern_prefix(key)
93
- "#{SplitIoClient.configuration.redis_namespace}/#{SplitIoClient.configuration.language}-*/latency.#{key}"
94
+ "#{@config.redis_namespace}/#{@config.language}-*/latency.#{key}"
94
95
  end
95
96
 
96
97
  def clear_gauges
@@ -7,14 +7,16 @@ module SplitIoClient
7
7
  def_delegators :@adapter, :add_count, :add_latency, :add_gauge, :counts, :latencies, :gauges,
8
8
  :clear_counts, :clear_latencies, :clear_gauges, :clear, :fix_latencies
9
9
 
10
- def initialize(adapter)
11
- @adapter = case adapter.class.to_s
10
+ def initialize(config)
11
+ super(config)
12
+ @adapter = case @config.metrics_adapter.class.to_s
12
13
  when 'SplitIoClient::Cache::Adapters::MemoryAdapter'
13
- Repositories::Metrics::MemoryRepository.new(adapter)
14
+ Repositories::Metrics::MemoryRepository.new(@config)
14
15
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
15
- Repositories::Metrics::RedisRepository.new(adapter)
16
+ Repositories::Metrics::RedisRepository.new(@config)
16
17
  end
17
18
  end
19
+
18
20
  end
19
21
  end
20
22
  end
@@ -1,6 +1,11 @@
1
1
  module SplitIoClient
2
2
  module Cache
3
3
  class Repository
4
+
5
+ def initialize(config)
6
+ @config = config
7
+ end
8
+
4
9
  def set_string(key, str)
5
10
  @adapter.set_string(namespace_key(key), str)
6
11
  end
@@ -12,11 +17,11 @@ module SplitIoClient
12
17
  protected
13
18
 
14
19
  def namespace_key(key = '')
15
- "#{SplitIoClient.configuration.redis_namespace}#{key}"
20
+ "#{@config.redis_namespace}#{key}"
16
21
  end
17
22
 
18
23
  def impressions_metrics_key(key)
19
- namespace_key("/#{SplitIoClient.configuration.language}-#{SplitIoClient.configuration.version}/#{SplitIoClient.configuration.machine_ip}/#{key}")
24
+ namespace_key("/#{@config.language}-#{@config.version}/#{@config.machine_ip}/#{key}")
20
25
  end
21
26
  end
22
27
  end
@@ -6,14 +6,15 @@ module SplitIoClient
6
6
 
7
7
  attr_reader :adapter
8
8
 
9
- def initialize(adapter)
10
- @adapter = case adapter.class.to_s
9
+ def initialize(config)
10
+ super(config)
11
+ @adapter = case @config.cache_adapter.class.to_s
11
12
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
12
- SplitIoClient::Cache::Adapters::CacheAdapter.new(adapter)
13
+ SplitIoClient::Cache::Adapters::CacheAdapter.new(@config)
13
14
  else
14
- adapter
15
+ @config.cache_adapter
15
16
  end
16
- @adapter.set_bool(namespace_key('.ready'), false) unless SplitIoClient.configuration.mode.equal?(:consumer)
17
+ @adapter.set_bool(namespace_key('.ready'), false) unless @config.mode.equal?(:consumer)
17
18
  end
18
19
 
19
20
  # Receives segment data, adds and removes segements from the store
@@ -6,14 +6,16 @@ module SplitIoClient
6
6
  class SplitsRepository < Repository
7
7
  attr_reader :adapter
8
8
 
9
- def initialize(adapter)
10
- @adapter = case adapter.class.to_s
9
+ def initialize(config)
10
+ super(config)
11
+ @tt_cache = {}
12
+ @adapter = case @config.cache_adapter.class.to_s
11
13
  when 'SplitIoClient::Cache::Adapters::RedisAdapter'
12
- SplitIoClient::Cache::Adapters::CacheAdapter.new(adapter)
14
+ SplitIoClient::Cache::Adapters::CacheAdapter.new(@config)
13
15
  else
14
- adapter
16
+ @config.cache_adapter
15
17
  end
16
- unless SplitIoClient.configuration.mode.equal?(:consumer)
18
+ unless @config.mode.equal?(:consumer)
17
19
  @adapter.set_string(namespace_key('.splits.till'), '-1')
18
20
  @adapter.initialize_map(namespace_key('.segments.registered'))
19
21
  end
@@ -21,12 +23,24 @@ module SplitIoClient
21
23
 
22
24
  def add_split(split)
23
25
  return unless split[:name]
26
+ existing_split = get_split(split[:name])
27
+
28
+ if(!existing_split)
29
+ increase_tt_name_count(split[:trafficTypeName])
30
+ elsif(existing_split[:trafficTypeName] != split[:trafficTypeName])
31
+ increase_tt_name_count(split[:trafficTypeName])
32
+ decrease_tt_name_count(existing_split[:trafficTypeName])
33
+ end
24
34
 
25
35
  @adapter.set_string(namespace_key(".split.#{split[:name]}"), split.to_json)
26
36
  end
27
37
 
28
- def remove_split(name)
29
- @adapter.delete(namespace_key(".split.#{name}"))
38
+ def remove_split(split)
39
+ tt_name = split[:trafficTypeName]
40
+
41
+ decrease_tt_name_count(split[:trafficTypeName])
42
+
43
+ @adapter.delete(namespace_key(".split.#{split[:name]}"))
30
44
  end
31
45
 
32
46
  def get_splits(names)
@@ -60,6 +74,21 @@ module SplitIoClient
60
74
  splits_hash
61
75
  end
62
76
 
77
+ def traffic_type_exists(tt_name)
78
+ case @adapter
79
+ when SplitIoClient::Cache::Adapters::CacheAdapter
80
+ tt_count = @adapter.string(namespace_key(".trafficType.#{tt_name}"))
81
+ begin
82
+ !tt_count.nil? && Integer(tt_count, 10) > 0
83
+ rescue StandardError => e
84
+ @config.logger.error("Error while parsing Traffic Type count: #{e.message}")
85
+ false
86
+ end
87
+ else
88
+ @tt_cache.key?(tt_name) && @tt_cache[tt_name] > 0
89
+ end
90
+ end
91
+
63
92
  # Return an array of Split Names excluding control keys like splits.till
64
93
  def split_names
65
94
  @adapter.find_strings_by_prefix(namespace_key('.split.'))
@@ -99,8 +128,26 @@ module SplitIoClient
99
128
  end
100
129
 
101
130
  def clear
131
+ @tt_cache.clear
132
+
102
133
  @adapter.clear(namespace_key)
103
134
  end
135
+
136
+ private
137
+
138
+ def increase_tt_name_count(tt_name)
139
+ return unless tt_name
140
+
141
+ @tt_cache[tt_name] = 0 unless @tt_cache[tt_name]
142
+ @tt_cache[tt_name] += 1
143
+ end
144
+
145
+ def decrease_tt_name_count(tt_name)
146
+ return unless tt_name
147
+
148
+ @tt_cache[tt_name] -= 1 if @tt_cache[tt_name]
149
+ @tt_cache.delete(tt_name) if @tt_cache[tt_name] == 0
150
+ end
104
151
  end
105
152
  end
106
153
  end
@@ -2,8 +2,9 @@ module SplitIoClient
2
2
  class ImpressionRouter
3
3
  attr_reader :router_thread
4
4
 
5
- def initialize
6
- @listener = SplitIoClient.configuration.impression_listener
5
+ def initialize(config)
6
+ @config = config
7
+ @listener = @config.impression_listener
7
8
 
8
9
  return unless @listener
9
10
 
@@ -44,12 +45,12 @@ module SplitIoClient
44
45
  end
45
46
 
46
47
  def router_thread
47
- SplitIoClient.configuration.threads[:impression_router] = Thread.new do
48
+ @config.threads[:impression_router] = Thread.new do
48
49
  loop do
49
50
  begin
50
51
  @listener.log(@queue.pop)
51
52
  rescue StandardError => error
52
- SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
53
+ @config.log_found_exception(__method__.to_s, error)
53
54
  end
54
55
  end
55
56
  end
@@ -4,8 +4,9 @@ module SplitIoClient
4
4
  module Cache
5
5
  module Senders
6
6
  class EventsSender
7
- def initialize(events_repository)
7
+ def initialize(events_repository, config)
8
8
  @events_repository = events_repository
9
+ @config = config
9
10
  end
10
11
 
11
12
  def call
@@ -25,19 +26,19 @@ module SplitIoClient
25
26
  private
26
27
 
27
28
  def events_thread
28
- SplitIoClient.configuration.threads[:events_sender] = Thread.new do
29
+ @config.threads[:events_sender] = Thread.new do
29
30
  begin
30
- SplitIoClient.configuration.logger.info('Starting events service')
31
-
31
+ @config.logger.info('Starting events service')
32
+
32
33
  loop do
33
34
  post_events
34
35
 
35
- sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.events_push_rate))
36
+ sleep(SplitIoClient::Utilities.randomize_interval(@config.events_push_rate))
36
37
  end
37
38
  rescue SplitIoClient::SDKShutdownException
38
39
  post_events
39
40
 
40
- SplitIoClient.configuration.logger.info('Posting events due to shutdown')
41
+ @config.logger.info('Posting events due to shutdown')
41
42
  end
42
43
  end
43
44
  end
@@ -4,14 +4,15 @@ module SplitIoClient
4
4
  module Cache
5
5
  module Senders
6
6
  class ImpressionsSender
7
- def initialize(impressions_repository, api_key)
7
+ def initialize(impressions_repository, api_key, config)
8
8
  @impressions_repository = impressions_repository
9
9
  @api_key = api_key
10
+ @config = config
10
11
  end
11
12
 
12
13
  def call
13
- if SplitIoClient.configuration.disable_impressions
14
- SplitIoClient.configuration.logger.info('Disabling impressions service by config')
14
+ if @config.disable_impressions
15
+ @config.logger.info('Disabling impressions service by config')
15
16
  return
16
17
  end
17
18
 
@@ -31,19 +32,19 @@ module SplitIoClient
31
32
  private
32
33
 
33
34
  def impressions_thread
34
- SplitIoClient.configuration.threads[:impressions_sender] = Thread.new do
35
+ @config.threads[:impressions_sender] = Thread.new do
35
36
  begin
36
- SplitIoClient.configuration.logger.info('Starting impressions service')
37
+ @config.logger.info('Starting impressions service')
37
38
 
38
39
  loop do
39
40
  post_impressions(false)
40
41
 
41
- sleep(SplitIoClient::Utilities.randomize_interval(SplitIoClient.configuration.impressions_refresh_rate))
42
+ sleep(SplitIoClient::Utilities.randomize_interval(@config.impressions_refresh_rate))
42
43
  end
43
44
  rescue SplitIoClient::SDKShutdownException
44
45
  post_impressions
45
46
 
46
- SplitIoClient.configuration.logger.info('Posting impressions due to shutdown')
47
+ @config.logger.info('Posting impressions due to shutdown')
47
48
  end
48
49
  end
49
50
  end
@@ -54,11 +55,11 @@ module SplitIoClient
54
55
 
55
56
  impressions_api.post(formatted_impressions)
56
57
  rescue StandardError => error
57
- SplitIoClient.configuration.log_found_exception(__method__.to_s, error)
58
+ @config.log_found_exception(__method__.to_s, error)
58
59
  end
59
60
 
60
61
  def impressions_api
61
- @impressions_api ||= SplitIoClient::Api::Impressions.new(@api_key)
62
+ @impressions_api ||= SplitIoClient::Api::Impressions.new(@api_key, @config)
62
63
  end
63
64
  end
64
65
  end