routemaster-drain 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
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