splitclient-rb 5.1.2 → 5.1.3.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aac78f1a43b52720c039260ceb19474cb8fd03fd473cbf0054c590c7e8d45e57
4
- data.tar.gz: d0cc36d7647956efbb9f0d455d1bf7aacfebca6960aa4fe304bd98e166d9752d
3
+ metadata.gz: 7470b6e84f8bf0cef00815acc17c0fa9d1f8ab81e6746676b19e9119ce12ba1f
4
+ data.tar.gz: 7d95234b01d68aa0da0bdf8a3dd07849836ca3a9194e9a56094bb054e597c0d4
5
5
  SHA512:
6
- metadata.gz: 48898f6530d4dfeea94dd20475bc204c1f4cbfe5c6d560565ad6ea3b33c756fa3c3e0f0cfa80a28919c5e88fc00a0bbc6e22d7a0031ca03b652bf8241d7ca651
7
- data.tar.gz: 14af6c54d0e1d164a59e2b735518f5bfdf80eb47b33d6fdb78415a056adf8ea2747ee7ee6a16f15c905611c8263ef5e48c964db8f4d3ad68395cecf6894106ae
6
+ metadata.gz: bc1135d77d83d1c037716ce4aaa2f9a9f40bcb386cc0efa1665bcd82e2fa2294907d1bc1f42e8fa72541179761d22965c0daee1b51a354677a5ca4bc5d20dc26
7
+ data.tar.gz: 9bc52d47fb482081015c4849e15105142de7033880f5d3de1cbef5a8766636389a055e35b4dfa5986a6e63136cc760ba945c702d80a31ae16cde8ad655a71906
data/CHANGES.txt CHANGED
@@ -1,3 +1,6 @@
1
+ 5.1.3
2
+ - Add cache wrapper to treatments and segments.
3
+
1
4
  5.1.2 (October 26th, 2018)
2
5
  - Add input validation for client API methods
3
6
 
data/Detailed-README.md CHANGED
@@ -301,6 +301,14 @@ _To use Redis, include `redis-rb` in your app's Gemfile._
301
301
 
302
302
  *default value* = (your current hostname)
303
303
 
304
+ **cache_ttl** : Time to live in seconds for the memory cache values when using Redis.
305
+
306
+ *default value* = `5`
307
+
308
+ **max_cache_size** : Maximum number of items held in the memory cache values when using Redis. When cache is full an LRU strategy for pruning shall be used.
309
+
310
+ *default value* = `500`
311
+
304
312
  **redis_url** : Redis URL or hash with configuration for the SDK to connect to. See [Redis#initialize](https://www.rubydoc.info/github/redis/redis-rb/Redis%3Ainitialize) for detailed information.
305
313
 
306
314
  *default value* = `'redis://127.0.0.1:6379/0'`
data/NEWS CHANGED
@@ -1,3 +1,7 @@
1
+ 5.1.3
2
+
3
+ Add cache wrapper to treatments and segments.
4
+
1
5
  5.1.2
2
6
 
3
7
  Add input validation for client API methods: get_treatment, get_treatments, track, manager
@@ -6,6 +6,7 @@ require 'splitclient-rb/exceptions'
6
6
  require 'splitclient-rb/cache/routers/impression_router'
7
7
  require 'splitclient-rb/cache/adapters/memory_adapters/map_adapter'
8
8
  require 'splitclient-rb/cache/adapters/memory_adapters/queue_adapter'
9
+ require 'splitclient-rb/cache/adapters/cache_adapter'
9
10
  require 'splitclient-rb/cache/adapters/memory_adapter'
10
11
  require 'splitclient-rb/cache/adapters/redis_adapter'
11
12
  require 'splitclient-rb/cache/repositories/repository'
@@ -0,0 +1,131 @@
1
+ require 'lru_redux'
2
+
3
+ module SplitIoClient
4
+ module Cache
5
+ module Adapters
6
+ class CacheAdapter
7
+ extend Forwardable
8
+ def_delegators :@adapter, :initialize_set, :set_bool, :pipelined
9
+
10
+ def initialize(adapter)
11
+ @cache = LruRedux::TTL::ThreadSafeCache.new(SplitIoClient.configuration.max_cache_size, SplitIoClient.configuration.cache_ttl)
12
+ @adapter = adapter
13
+ end
14
+
15
+ def delete(key)
16
+ @cache.delete(key)
17
+ @adapter.delete(key)
18
+ end
19
+
20
+ def clear(namespace_key)
21
+ @cache.clear
22
+ @adapter.clear(namespace_key)
23
+ end
24
+
25
+ def string(key)
26
+ value = get(key)
27
+ return value if value
28
+ value = @adapter.string(key)
29
+ add(key, value)
30
+ value
31
+ end
32
+
33
+ def set_string(key, value)
34
+ add(key, value)
35
+ @adapter.set_string(key, value)
36
+ end
37
+
38
+ def multiple_strings(keys)
39
+ cached_values = keys.each_with_object({}) do |key, memo|
40
+ memo[key] = get(key)
41
+ end
42
+
43
+ non_cached_keys = []
44
+ cached_values.delete_if{ |k,v| v.nil? ? non_cached_keys << k : false }
45
+
46
+ if non_cached_keys.any?
47
+ new_values = @adapter.multiple_strings(non_cached_keys)
48
+
49
+ new_values.keys.each do |key, value|
50
+ add(key, value)
51
+ end
52
+
53
+ cached_values.merge!(new_values)
54
+ end
55
+
56
+ cached_values
57
+ end
58
+
59
+ def find_strings_by_prefix(prefix)
60
+ @adapter.find_strings_by_prefix(prefix)
61
+ end
62
+
63
+ def exists?(key)
64
+ cached_value = get(key)
65
+ if cached_value.nil?
66
+ @adapter.exists?(key)
67
+ else
68
+ true
69
+ end
70
+ end
71
+
72
+ def add_to_set(key, values)
73
+ if values.is_a? Array
74
+ values.each { |value| add_to_map(key, value, 1) }
75
+ else
76
+ add_to_map(key, values, 1)
77
+ end
78
+ @adapter.add_to_set(key, values)
79
+ end
80
+
81
+ def in_set?(key, field)
82
+ cached_value = get(key)
83
+ if cached_value.nil?
84
+ return @adapter.in_set?(key, field)
85
+ end
86
+ cached_value.key?(field)
87
+ end
88
+
89
+ def get_set(key)
90
+ cached_value = get(key)
91
+ if cached_value.nil?
92
+ return @adapter.get_set(key)
93
+ end
94
+ cached_value.keys
95
+ end
96
+
97
+ def delete_from_set(key, fields)
98
+ cached_value = get(key)
99
+ if cached_value
100
+ if fields.is_a? Array
101
+ fields.each { |field| cached_value.delete(field) }
102
+ else
103
+ cached_value.delete(fields)
104
+ end
105
+ end
106
+
107
+ @adapter.delete_from_set(key, fields)
108
+ end
109
+
110
+ def initialize_map(key)
111
+ @cache[key] = Concurrent::Map.new
112
+ end
113
+
114
+ private
115
+
116
+ def add_to_map(key, field, value)
117
+ initialize_map(key) unless get(key)
118
+ get(key).put(field.to_s, value.to_s)
119
+ end
120
+
121
+ def add(key, value)
122
+ @cache[key] = value.to_s unless value.nil?
123
+ end
124
+
125
+ def get(key)
126
+ @cache[key]
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -7,7 +7,12 @@ module SplitIoClient
7
7
  attr_reader :adapter
8
8
 
9
9
  def initialize(adapter)
10
- @adapter = adapter
10
+ @adapter = case adapter.class.to_s
11
+ when 'SplitIoClient::Cache::Adapters::RedisAdapter'
12
+ SplitIoClient::Cache::Adapters::CacheAdapter.new(adapter)
13
+ else
14
+ adapter
15
+ end
11
16
  @adapter.set_bool(namespace_key('.ready'), false) unless SplitIoClient.configuration.mode == :consumer
12
17
  end
13
18
 
@@ -7,7 +7,12 @@ module SplitIoClient
7
7
  attr_reader :adapter
8
8
 
9
9
  def initialize(adapter)
10
- @adapter = adapter
10
+ @adapter = case adapter.class.to_s
11
+ when 'SplitIoClient::Cache::Adapters::RedisAdapter'
12
+ SplitIoClient::Cache::Adapters::CacheAdapter.new(adapter)
13
+ else
14
+ adapter
15
+ end
11
16
  unless SplitIoClient.configuration.mode == :consumer
12
17
  @adapter.set_string(namespace_key('.splits.till'), '-1')
13
18
  @adapter.initialize_map(namespace_key('.segments.registered'))
@@ -33,6 +33,8 @@ module SplitIoClient
33
33
  # @option opts [Int] :impressions_queue_size Size of the impressions queue in the memory repository. Once reached, newer impressions will be dropped
34
34
  # @option opts [Int] :impressions_bulk_size Max number of impressions to be sent to the backend on each post
35
35
  # @option opts [#log] :impression_listener this object will capture all impressions and process them through `#log`
36
+ # @option opts [Int] :cache_ttl Time to live in seconds for the memory cache values when using Redis.
37
+ # @option opts [Int] :max_cache_size Max number of items to be held in the memory cache before prunning when using Redis.
36
38
  # @return [type] SplitConfig with configuration options
37
39
  def initialize(opts = {})
38
40
  @base_uri = (opts[:base_uri] || SplitConfig.default_base_uri).chomp('/')
@@ -70,6 +72,9 @@ module SplitIoClient
70
72
  @machine_name = opts[:machine_name] || SplitConfig.machine_hostname
71
73
  @machine_ip = opts[:machine_ip] || SplitConfig.machine_ip
72
74
 
75
+ @cache_ttl = opts[:cache_ttl] || SplitConfig.cache_ttl
76
+ @max_cache_size = opts[:max_cache_size] || SplitConfig.max_cache_size
77
+
73
78
  @language = opts[:language] || 'ruby'
74
79
  @version = opts[:version] || SplitIoClient::VERSION
75
80
 
@@ -176,6 +181,9 @@ module SplitIoClient
176
181
  attr_accessor :machine_ip
177
182
  attr_accessor :machine_name
178
183
 
184
+ attr_accessor :cache_ttl
185
+ attr_accessor :max_cache_size
186
+
179
187
  attr_accessor :language
180
188
  attr_accessor :version
181
189
 
@@ -357,6 +365,21 @@ module SplitIoClient
357
365
  false
358
366
  end
359
367
 
368
+ #
369
+ # The default cache time to live
370
+ #
371
+ # @return [boolean]
372
+ def self.cache_ttl
373
+ 5
374
+ end
375
+
376
+ # The default max cache size
377
+ #
378
+ # @return [boolean]
379
+ def self.max_cache_size
380
+ 500
381
+ end
382
+
360
383
  #
361
384
  # custom logger of exceptions
362
385
  #
@@ -1,3 +1,3 @@
1
1
  module SplitIoClient
2
- VERSION = '5.1.2'
2
+ VERSION = '5.1.3.pre.rc1'
3
3
  end
@@ -46,11 +46,13 @@ Gem::Specification.new do |spec|
46
46
  spec.add_development_dependency 'rspec'
47
47
  spec.add_development_dependency 'rubocop', '0.59.0'
48
48
  spec.add_development_dependency 'simplecov'
49
+ spec.add_development_dependency 'timecop'
49
50
  spec.add_development_dependency 'webmock'
50
51
 
51
52
  spec.add_runtime_dependency 'concurrent-ruby', '~> 1.0'
52
53
  spec.add_runtime_dependency 'faraday', '>= 0.8'
53
54
  spec.add_runtime_dependency 'json', '>= 1.8'
55
+ spec.add_runtime_dependency 'lru_redux'
54
56
  spec.add_runtime_dependency 'net-http-persistent', '~> 2.9'
55
57
  spec.add_runtime_dependency 'redis', '>= 3.2'
56
58
  spec.add_runtime_dependency 'thread_safe', '>= 0.3'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: splitclient-rb
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.1.2
4
+ version: 5.1.3.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Split Software
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-10-26 00:00:00.000000000 Z
11
+ date: 2018-11-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: allocation_stats
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: timecop
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: webmock
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +206,20 @@ dependencies:
192
206
  - - ">="
193
207
  - !ruby/object:Gem::Version
194
208
  version: '1.8'
209
+ - !ruby/object:Gem::Dependency
210
+ name: lru_redux
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: '0'
216
+ type: :runtime
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - ">="
221
+ - !ruby/object:Gem::Version
222
+ version: '0'
195
223
  - !ruby/object:Gem::Dependency
196
224
  name: net-http-persistent
197
225
  requirement: !ruby/object:Gem::Requirement
@@ -261,6 +289,7 @@ files:
261
289
  - lib/murmurhash/murmurhash.jar
262
290
  - lib/murmurhash/murmurhash_mri.rb
263
291
  - lib/splitclient-rb.rb
292
+ - lib/splitclient-rb/cache/adapters/cache_adapter.rb
264
293
  - lib/splitclient-rb/cache/adapters/memory_adapter.rb
265
294
  - lib/splitclient-rb/cache/adapters/memory_adapters/map_adapter.rb
266
295
  - lib/splitclient-rb/cache/adapters/memory_adapters/queue_adapter.rb
@@ -357,9 +386,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
357
386
  version: '0'
358
387
  required_rubygems_version: !ruby/object:Gem::Requirement
359
388
  requirements:
360
- - - ">="
389
+ - - ">"
361
390
  - !ruby/object:Gem::Version
362
- version: '0'
391
+ version: 1.3.1
363
392
  requirements: []
364
393
  rubyforge_project:
365
394
  rubygems_version: 2.7.6