routemaster-drain 3.0.1 → 3.0.2

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
  SHA1:
3
- metadata.gz: 193d7dd526f02d0397233f0c2868e74aedb41a23
4
- data.tar.gz: 9a3c37a909a17321b305cd9c5d0bf916b71b722b
3
+ metadata.gz: 2d3a7e45eaf612d87b49876ad21714abaf7df4ca
4
+ data.tar.gz: 86494043fed1e03fe0b99c3377b454defc814621
5
5
  SHA512:
6
- metadata.gz: d9dfc1c8da243ee0e56a30f77f5af28ddc374200c94de8341b77cf5f69a4a8a892426b310b59c0b5dfa8fe2763aa2bb59435e229201319a6dff94319d4de7737
7
- data.tar.gz: a09d4315e6d6b9d0993aa8c35c93a5a5e2790339180159bc5346b497dc64b38b9617abe3ab8e0d2d4d771c0a4cd96e127df3ae961feb2140e35cd22a88067b13
6
+ metadata.gz: 18fae881aefa55f9a9b7807d07b7d9b8c1db5438cbc4b60d912de6925f874837266e5ab1e732f5ca9b769f21a81e7a6efc58dacf1f3ee0826ec0b22bb314e569
7
+ data.tar.gz: d86089d7ac3130d8dae61c623a30e65a374f434d95360e6c77fc13d44160f6bc0e36784437e7eed8eb7d23c55f5fbbb4fa26ed776c07ffa73f2e93399458ba3c
data/CHANGELOG.md CHANGED
@@ -1,3 +1,10 @@
1
+ ### 3.0.2 (2017-09-05)
2
+
3
+ Bug fixes:
4
+
5
+ - Fixes a condition where cache keys in Redis would not expire (#63)
6
+
7
+
1
8
  ### 3.0.1 (2017-08-08)
2
9
 
3
10
  Bug fixes:
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- routemaster-drain (3.0.1)
4
+ routemaster-drain (3.0.2)
5
5
  addressable
6
6
  concurrent-ruby
7
7
  faraday (>= 0.9.0)
@@ -37,7 +37,7 @@ GEM
37
37
  dotenv (2.1.1)
38
38
  ethon (0.10.1)
39
39
  ffi (>= 1.3.0)
40
- faraday (0.12.1)
40
+ faraday (0.12.2)
41
41
  multipart-post (>= 1.2, < 3)
42
42
  faraday_middleware (0.12.2)
43
43
  faraday (>= 0.7.4, < 1.0)
@@ -133,7 +133,7 @@ GEM
133
133
  slop (3.6.0)
134
134
  thor (0.19.4)
135
135
  tilt (2.0.5)
136
- typhoeus (1.1.2)
136
+ typhoeus (1.3.0)
137
137
  ethon (>= 0.9.0)
138
138
  url (0.3.2)
139
139
  vegas (0.1.11)
@@ -168,4 +168,4 @@ DEPENDENCIES
168
168
  webmock
169
169
 
170
170
  BUNDLED WITH
171
- 1.15.3
171
+ 1.15.4
data/README.md CHANGED
@@ -17,6 +17,7 @@ combining middleware.
17
17
  <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
18
18
 
19
19
  - [Installation](#installation)
20
+ - [Upgrading](#upgrading)
20
21
  - [Illustrated use cases](#illustrated-use-cases)
21
22
  - [Simply receive events from Routemaster](#simply-receive-events-from-routemaster)
22
23
  - [Receive change notifications without duplicates](#receive-change-notifications-without-duplicates)
@@ -77,6 +78,24 @@ Routemaster::RedisBroker.instance.inject(
77
78
  )
78
79
  ```
79
80
 
81
+ ## Upgrading
82
+
83
+
84
+ If upgrading from any version between 2.4.0 and 3.0.1, and are using caching,
85
+ your cache may be corrupted by entries that lack a TTL (which will eventually
86
+ cause your Redis
87
+ storage to blow up).
88
+
89
+ We provide a tool to fix your data. With your environment loaded and configured
90
+ (e.g. from a Rails console), run:
91
+
92
+ ```ruby
93
+ Routemaster::Tasks::FixCacheTTL.new.call
94
+ ```
95
+
96
+ This will scan your cache and add TTLs where missing.
97
+
98
+
80
99
  ## Illustrated use cases
81
100
 
82
101
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- routemaster-drain (3.0.1)
4
+ routemaster-drain (3.0.2)
5
5
  addressable
6
6
  concurrent-ruby
7
7
  faraday (>= 0.9.0)
@@ -67,7 +67,7 @@ GEM
67
67
  erubis (2.7.0)
68
68
  ethon (0.10.1)
69
69
  ffi (>= 1.3.0)
70
- faraday (0.12.1)
70
+ faraday (0.12.2)
71
71
  multipart-post (>= 1.2, < 3)
72
72
  faraday_middleware (0.12.2)
73
73
  faraday (>= 0.7.4, < 1.0)
@@ -200,7 +200,7 @@ GEM
200
200
  treetop (1.4.15)
201
201
  polyglot
202
202
  polyglot (>= 0.3.1)
203
- typhoeus (1.1.2)
203
+ typhoeus (1.3.0)
204
204
  ethon (>= 0.9.0)
205
205
  tzinfo (0.3.53)
206
206
  url (0.3.2)
@@ -237,4 +237,4 @@ DEPENDENCIES
237
237
  webmock
238
238
 
239
239
  BUNDLED WITH
240
- 1.15.3
240
+ 1.15.4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- routemaster-drain (3.0.1)
4
+ routemaster-drain (3.0.2)
5
5
  addressable
6
6
  concurrent-ruby
7
7
  faraday (>= 0.9.0)
@@ -74,7 +74,7 @@ GEM
74
74
  erubis (2.7.0)
75
75
  ethon (0.10.1)
76
76
  ffi (>= 1.3.0)
77
- faraday (0.12.1)
77
+ faraday (0.12.2)
78
78
  multipart-post (>= 1.2, < 3)
79
79
  faraday_middleware (0.12.2)
80
80
  faraday (>= 0.7.4, < 1.0)
@@ -216,7 +216,7 @@ GEM
216
216
  thor (0.19.4)
217
217
  thread_safe (0.3.6)
218
218
  tilt (2.0.7)
219
- typhoeus (1.1.2)
219
+ typhoeus (1.3.0)
220
220
  ethon (>= 0.9.0)
221
221
  tzinfo (1.2.3)
222
222
  thread_safe (~> 0.1)
@@ -254,4 +254,4 @@ DEPENDENCIES
254
254
  webmock
255
255
 
256
256
  BUNDLED WITH
257
- 1.15.3
257
+ 1.15.4
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ..
3
3
  specs:
4
- routemaster-drain (3.0.1)
4
+ routemaster-drain (3.0.2)
5
5
  addressable
6
6
  concurrent-ruby
7
7
  faraday (>= 0.9.0)
@@ -77,7 +77,7 @@ GEM
77
77
  erubis (2.7.0)
78
78
  ethon (0.10.1)
79
79
  ffi (>= 1.3.0)
80
- faraday (0.12.1)
80
+ faraday (0.12.2)
81
81
  multipart-post (>= 1.2, < 3)
82
82
  faraday_middleware (0.12.2)
83
83
  faraday (>= 0.7.4, < 1.0)
@@ -216,7 +216,7 @@ GEM
216
216
  sprockets (>= 3.0.0)
217
217
  thor (0.19.4)
218
218
  thread_safe (0.3.6)
219
- typhoeus (1.1.2)
219
+ typhoeus (1.3.0)
220
220
  ethon (>= 0.9.0)
221
221
  tzinfo (1.2.3)
222
222
  thread_safe (~> 0.1)
@@ -257,4 +257,4 @@ DEPENDENCIES
257
257
  webmock
258
258
 
259
259
  BUNDLED WITH
260
- 1.15.3
260
+ 1.15.4
@@ -1,7 +1,9 @@
1
1
  module Routemaster
2
2
  class CacheKey
3
+ PREFIX = 'cache:'.freeze
4
+
3
5
  def self.url_key(url)
4
- "cache:#{url}"
6
+ "#{PREFIX}#{url}"
5
7
  end
6
8
  end
7
9
  end
@@ -1,5 +1,5 @@
1
1
  module Routemaster
2
2
  module Drain
3
- VERSION = '3.0.1'
3
+ VERSION = '3.0.2'.freeze
4
4
  end
5
5
  end
@@ -1,21 +1,34 @@
1
1
  require 'routemaster/cache_key'
2
2
  module Routemaster
3
3
  class EventIndex
4
- attr_reader :url, :cache
5
-
6
4
  def initialize(url, cache: Config.cache_redis)
7
5
  @url = url
8
6
  @cache = cache
9
7
  end
10
8
 
11
9
  def increment
12
- i = cache.hincrby(CacheKey.url_key(url), 'current_index', 1).to_i
13
- Config.logger.debug("DRAIN: Increment #{@url} to #{i}") if Config.logger.debug?
14
- i
10
+ _node do |cache, key|
11
+ cache.multi do |m|
12
+ m.hincrby(key, 'current_index', 1)
13
+ m.expire(key, Config.cache_expiry)
14
+ end
15
+ end
16
+ self
15
17
  end
16
18
 
17
19
  def current
18
- (cache.hget(CacheKey.url_key(url), 'current_index') || 0).to_i
20
+ (@cache.hget(_key, 'current_index') || 0).to_i
21
+ end
22
+
23
+ private
24
+
25
+ def _node
26
+ namespaced_key = "#{@cache.namespace}:#{_key}"
27
+ yield @cache.redis.node_for(namespaced_key), namespaced_key
28
+ end
29
+
30
+ def _key
31
+ @_key ||= CacheKey.url_key(@url)
19
32
  end
20
33
  end
21
34
  end
@@ -0,0 +1,45 @@
1
+ require 'routemaster/cache_key'
2
+
3
+ module Routemaster
4
+ module Tasks
5
+ class FixCacheTTL
6
+ def initialize(cache: Config.cache_redis, batch_size: 100)
7
+ @cache = cache
8
+ @batch_size = batch_size
9
+ end
10
+
11
+ def call
12
+ pattern = "#{@cache.namespace}:#{CacheKey::PREFIX}*"
13
+ _each_key_batch(pattern) do |node, keys|
14
+ _fix_keys(node, keys)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def _each_key_batch(pattern)
21
+ @cache.redis.nodes.each do |node|
22
+ cursor = 0
23
+ loop do
24
+ cursor, keys = node.scan(cursor, count: @batch_size, match: pattern)
25
+ yield node, keys
26
+ break if cursor.to_i == 0
27
+ end
28
+ end
29
+ end
30
+
31
+ def _fix_keys(node, keys)
32
+ ttls = node.pipelined do |p|
33
+ keys.each { |k| p.ttl(k) }
34
+ end
35
+
36
+ node.pipelined do |p|
37
+ keys.zip(ttls).each do |k,ttl|
38
+ next unless ttl < 0
39
+ p.expire(k, Config.cache_expiry)
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,29 @@
1
+ require 'routemaster/event_index'
2
+ require 'spec/support/uses_redis'
3
+
4
+ describe Routemaster::EventIndex do
5
+ uses_redis
6
+
7
+ let(:cache) { Routemaster::Config.cache_redis }
8
+ let(:url) { 'https://example.com/widgets/1234' }
9
+ subject { described_class.new(url, cache: cache) }
10
+
11
+ describe '#increment' do
12
+ it 'increases #current' do
13
+ expect {
14
+ subject.increment
15
+ }.to change {
16
+ subject.current
17
+ }.from(0).to(1)
18
+ end
19
+
20
+ it 'leaves all keys with TTLs' do
21
+ subject.increment
22
+ cache.redis.nodes.each do |node|
23
+ node.keys.each do |key|
24
+ expect(node.ttl(key)).to be > 0
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ require 'routemaster/tasks/fix_cache_ttl'
2
+ require 'spec/support/uses_redis'
3
+
4
+ describe Routemaster::Tasks::FixCacheTTL do
5
+ uses_redis
6
+
7
+ let(:cache) { Routemaster::Config.cache_redis }
8
+ subject { described_class.new(cache: cache, batch_size: 5) }
9
+
10
+ before do
11
+ # add keys without a TTL, that aren't cache keys
12
+ @ignored_keys = (1..20).map { |n| "fubar:#{n}".tap { |k| cache.set(k, n) } }
13
+
14
+ # add cache keys with a pre-existing TTL
15
+ @good_keys = (1..20).map { |n| "cache:good-#{n}".tap { |k| cache.set(k, n, ex: n + 1_000) } }
16
+
17
+ # add cache keys without a TTL
18
+ @bad_keys = (1..20).map { |n| "cache:bad-#{n}".tap { |k| cache.set("cache:bad-#{n}", n) } }
19
+ end
20
+
21
+ it 'leaves non-cache keys alone' do
22
+ subject.call
23
+ @ignored_keys.each { |k|
24
+ expect(cache.ttl(k)).to eq -1
25
+ }
26
+ end
27
+
28
+ it 'adds a TTL to broken cache keys' do
29
+ subject.call
30
+ @bad_keys.each { |k|
31
+ expect(cache.ttl(k)).to be > 100_000
32
+ }
33
+ end
34
+
35
+ it 'leaves the TTL of good cache keys alone' do
36
+ subject.call
37
+ @good_keys.each { |k|
38
+ expect(0..2_000).to include cache.ttl(k)
39
+ }
40
+ end
41
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: routemaster-drain
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.1
4
+ version: 3.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Letessier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-08 00:00:00.000000000 Z
11
+ date: 2017-09-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: addressable
@@ -209,6 +209,7 @@ files:
209
209
  - lib/routemaster/responses/hateoas_enumerable_response.rb
210
210
  - lib/routemaster/responses/hateoas_response.rb
211
211
  - lib/routemaster/responses/response_promise.rb
212
+ - lib/routemaster/tasks/fix_cache_ttl.rb
212
213
  - routemaster-drain.gemspec
213
214
  - spec/routemaster/api_client_spec.rb
214
215
  - spec/routemaster/cache_spec.rb
@@ -221,6 +222,7 @@ files:
221
222
  - spec/routemaster/drain/caching_spec.rb
222
223
  - spec/routemaster/drain/mapping_spec.rb
223
224
  - spec/routemaster/drain/terminator_spec.rb
225
+ - spec/routemaster/event_index_spec.rb
224
226
  - spec/routemaster/integration/api_client_spec.rb
225
227
  - spec/routemaster/integration/cache_spec.rb
226
228
  - spec/routemaster/jobs/backends/backend_examples.rb
@@ -240,6 +242,7 @@ files:
240
242
  - spec/routemaster/responses/hateoas_enumerable_response_spec.rb
241
243
  - spec/routemaster/responses/hateoas_response_spec.rb
242
244
  - spec/routemaster/responses/response_promise_spec.rb
245
+ - spec/routemaster/tasks/fix_cache_ttl_spec.rb
243
246
  - spec/spec_helper.rb
244
247
  - spec/support/breakpoint_class.rb
245
248
  - spec/support/events.rb
@@ -269,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
269
272
  version: '0'
270
273
  requirements: []
271
274
  rubyforge_project:
272
- rubygems_version: 2.6.8
275
+ rubygems_version: 2.6.11
273
276
  signing_key:
274
277
  specification_version: 4
275
278
  summary: Event receiver for the Routemaster bus
@@ -285,6 +288,7 @@ test_files:
285
288
  - spec/routemaster/drain/caching_spec.rb
286
289
  - spec/routemaster/drain/mapping_spec.rb
287
290
  - spec/routemaster/drain/terminator_spec.rb
291
+ - spec/routemaster/event_index_spec.rb
288
292
  - spec/routemaster/integration/api_client_spec.rb
289
293
  - spec/routemaster/integration/cache_spec.rb
290
294
  - spec/routemaster/jobs/backends/backend_examples.rb
@@ -304,6 +308,7 @@ test_files:
304
308
  - spec/routemaster/responses/hateoas_enumerable_response_spec.rb
305
309
  - spec/routemaster/responses/hateoas_response_spec.rb
306
310
  - spec/routemaster/responses/response_promise_spec.rb
311
+ - spec/routemaster/tasks/fix_cache_ttl_spec.rb
307
312
  - spec/spec_helper.rb
308
313
  - spec/support/breakpoint_class.rb
309
314
  - spec/support/events.rb