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 +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +4 -4
- data/README.md +19 -0
- data/gemfiles/rails_3.gemfile.lock +4 -4
- data/gemfiles/rails_4.gemfile.lock +4 -4
- data/gemfiles/rails_5.gemfile.lock +4 -4
- data/lib/routemaster/cache_key.rb +3 -1
- data/lib/routemaster/drain.rb +1 -1
- data/lib/routemaster/event_index.rb +19 -6
- data/lib/routemaster/tasks/fix_cache_ttl.rb +45 -0
- data/spec/routemaster/event_index_spec.rb +29 -0
- data/spec/routemaster/tasks/fix_cache_ttl_spec.rb +41 -0
- metadata +8 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2d3a7e45eaf612d87b49876ad21714abaf7df4ca
|
|
4
|
+
data.tar.gz: 86494043fed1e03fe0b99c3377b454defc814621
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 18fae881aefa55f9a9b7807d07b7d9b8c1db5438cbc4b60d912de6925f874837266e5ab1e732f5ca9b769f21a81e7a6efc58dacf1f3ee0826ec0b22bb314e569
|
|
7
|
+
data.tar.gz: d86089d7ac3130d8dae61c623a30e65a374f434d95360e6c77fc13d44160f6bc0e36784437e7eed8eb7d23c55f5fbbb4fa26ed776c07ffa73f2e93399458ba3c
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (3.0.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
240
|
+
1.15.4
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (3.0.
|
|
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.
|
|
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.
|
|
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.
|
|
257
|
+
1.15.4
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (3.0.
|
|
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.
|
|
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.
|
|
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.
|
|
260
|
+
1.15.4
|
data/lib/routemaster/drain.rb
CHANGED
|
@@ -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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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(
|
|
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.
|
|
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-
|
|
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.
|
|
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
|