routemaster-drain 2.4.4 → 2.5.0
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 +12 -0
- data/Gemfile.lock +3 -2
- data/README.md +23 -4
- data/gemfiles/rails_3.gemfile.lock +9 -8
- data/gemfiles/rails_4.gemfile.lock +11 -10
- data/gemfiles/rails_5.gemfile.lock +45 -44
- data/lib/routemaster/drain/basic.rb +0 -1
- data/lib/routemaster/drain/cache_busting.rb +38 -0
- data/lib/routemaster/drain/caching.rb +4 -1
- data/lib/routemaster/drain/mapping.rb +2 -1
- data/lib/routemaster/drain.rb +1 -1
- data/lib/routemaster/middleware/authenticate.rb +1 -2
- data/lib/routemaster/middleware/cache.rb +1 -2
- data/lib/routemaster/middleware/dirty.rb +1 -4
- data/lib/routemaster/middleware/expire_cache.rb +20 -0
- data/lib/routemaster/middleware/filter.rb +2 -2
- data/lib/routemaster/middleware/payload_filter.rb +10 -0
- data/lib/routemaster/middleware/siphon.rb +32 -0
- data/lib/routemaster/resources/rest_resource.rb +18 -8
- data/routemaster-drain.gemspec +1 -0
- data/spec/routemaster/api_client_spec.rb +1 -6
- data/spec/routemaster/drain/cache_busting_spec.rb +43 -0
- data/spec/routemaster/drain/caching_spec.rb +10 -4
- data/spec/routemaster/drain/mapping_spec.rb +10 -7
- data/spec/routemaster/middleware/cache_spec.rb +0 -5
- data/spec/routemaster/middleware/root_post_only_spec.rb +0 -4
- data/spec/routemaster/middleware/siphon_spec.rb +46 -0
- data/spec/routemaster/resources/rest_resource_spec.rb +35 -26
- data/spec/support/siphon.rb +13 -0
- metadata +26 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 174d544b122fdee4b52eb706ce2d1324e416eea4
|
|
4
|
+
data.tar.gz: 2d33ba614a48f0e613adc1941a2126d17354b2a0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0b3cc42bfe4e62e6ecc2b60e71c69525d669447c0601ea5bf06a1b79c1fdab7b6c1e20e1494acb980ac5097615231b2b22fda210cca1fc43b5fd87875667d453
|
|
7
|
+
data.tar.gz: 4688fb67eb80241cf5fe28e5eed11be1617d083f8625fe378de960ee2506d45f105666ab556e69adb0944d592755d2ec9b302c31b6c8864ebdcc23070e02734d
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
### 2.5.0 (2017-04-11)
|
|
2
|
+
|
|
3
|
+
Features:
|
|
4
|
+
|
|
5
|
+
- Allow template urls to be defined in services (#38)
|
|
6
|
+
- Adds the `Siphon` middleware (#39, #44)
|
|
7
|
+
- Adds `CacheBusting` middleware (#40)
|
|
8
|
+
|
|
9
|
+
Bug fixes:
|
|
10
|
+
|
|
11
|
+
- Caching middleware always busts the cache on events - preventing stale events being cached in some circumstances (#40)
|
|
12
|
+
|
|
1
13
|
### 2.4.4 (2017-03-27)
|
|
2
14
|
|
|
3
15
|
Features:
|
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (2.
|
|
4
|
+
routemaster-drain (2.5.0)
|
|
5
|
+
addressable
|
|
5
6
|
concurrent-ruby
|
|
6
7
|
faraday (>= 0.9.0)
|
|
7
8
|
faraday_middleware
|
|
@@ -36,7 +37,7 @@ GEM
|
|
|
36
37
|
dotenv (2.1.1)
|
|
37
38
|
ethon (0.10.1)
|
|
38
39
|
ffi (>= 1.3.0)
|
|
39
|
-
faraday (0.
|
|
40
|
+
faraday (0.12.0.1)
|
|
40
41
|
multipart-post (>= 1.2, < 3)
|
|
41
42
|
faraday_middleware (0.11.0.1)
|
|
42
43
|
faraday (>= 0.7.4, < 1.0)
|
data/README.md
CHANGED
|
@@ -199,7 +199,7 @@ response = @cache.fget('https://example.com/widgets/123')
|
|
|
199
199
|
puts response.body.id
|
|
200
200
|
```
|
|
201
201
|
|
|
202
|
-
In this example,
|
|
202
|
+
In this example, if your app was notified by Routemaster about Widget #123, the
|
|
203
203
|
cache will be very likely to be hit; and it will be invalidated automatically
|
|
204
204
|
whenever the drain gets notified about a change on that widget.
|
|
205
205
|
|
|
@@ -210,6 +210,17 @@ See
|
|
|
210
210
|
[rubydoc](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Cache)
|
|
211
211
|
for more details on `Cache`.
|
|
212
212
|
|
|
213
|
+
### Expire Cache data for all notified resources
|
|
214
|
+
|
|
215
|
+
You may wish to maintain a coherent cache but don't need the cache to be warmed
|
|
216
|
+
before you process incoming events. In that case, use the cache as detailed above
|
|
217
|
+
but swap the `Caching` drain out for `CachingBusting`
|
|
218
|
+
|
|
219
|
+
```ruby
|
|
220
|
+
require 'routemaster/drain/machine'
|
|
221
|
+
$app = Routemaster::Drain::CachingBusting.new
|
|
222
|
+
```
|
|
223
|
+
|
|
213
224
|
## HTTP Client
|
|
214
225
|
The Drain is using a Faraday http client for communication between services. The client
|
|
215
226
|
comes with a convenient caching mechanism as a default and supports custom response materialization.
|
|
@@ -277,9 +288,10 @@ response.user.show(1)
|
|
|
277
288
|
|
|
278
289
|
The more elaborate drains are built with two components which can also be used
|
|
279
290
|
independently,
|
|
280
|
-
[`Dirty::Map`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Map)
|
|
281
|
-
and
|
|
282
|
-
[`
|
|
291
|
+
[`Dirty::Map`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Map),
|
|
292
|
+
[`Dirty::Filter`](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Dirty/Filter) and
|
|
293
|
+
[`Middleware::Siphon`](http://www.rubydoc.info/github/deliveroo/routemaster-drain/master/Routemaster/Middleware/Siphon).
|
|
294
|
+
|
|
283
295
|
|
|
284
296
|
### Dirty map
|
|
285
297
|
|
|
@@ -314,6 +326,11 @@ It stores transient state in Redis and will emit `:entity_changed` events
|
|
|
314
326
|
whenever an entity has changed. This event can usefully be fed into a dirty map,
|
|
315
327
|
as in `Receiver::Filter` for instance.
|
|
316
328
|
|
|
329
|
+
### Siphon
|
|
330
|
+
|
|
331
|
+
[`Middleware::Siphon`](http://www.rubydoc.info/github/deliveroo/routemaster-drain/master/Routemaster/Middleware/Siphon) extracts
|
|
332
|
+
payloads from the middleware chain, allowing them to be processed separately. This is useful for event topics where the update frequency is not well suited
|
|
333
|
+
to frequent caching. For example, a location update event which you'd expect to receive every few seconds.
|
|
317
334
|
|
|
318
335
|
## Contributing
|
|
319
336
|
|
|
@@ -327,3 +344,5 @@ Do not bump version numbers on branches (a maintainer will do this when cutting
|
|
|
327
344
|
a release); but please do describe your changes in the `CHANGELOG` (at the top,
|
|
328
345
|
without a version number).
|
|
329
346
|
|
|
347
|
+
If you have changed dependencies, you need to run `appraisal update` to make
|
|
348
|
+
sure the various version specific gemfiles are updated.
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (2.
|
|
4
|
+
routemaster-drain (2.5.0)
|
|
5
|
+
addressable
|
|
5
6
|
concurrent-ruby
|
|
6
7
|
faraday (>= 0.9.0)
|
|
7
8
|
faraday_middleware
|
|
@@ -41,7 +42,7 @@ GEM
|
|
|
41
42
|
activesupport (3.2.22.5)
|
|
42
43
|
i18n (~> 0.6, >= 0.6.4)
|
|
43
44
|
multi_json (~> 1.0)
|
|
44
|
-
addressable (2.5.
|
|
45
|
+
addressable (2.5.1)
|
|
45
46
|
public_suffix (~> 2.0, >= 2.0.2)
|
|
46
47
|
appraisal (2.1.0)
|
|
47
48
|
bundler
|
|
@@ -50,7 +51,7 @@ GEM
|
|
|
50
51
|
arel (3.0.3)
|
|
51
52
|
builder (3.0.4)
|
|
52
53
|
byebug (9.0.6)
|
|
53
|
-
codecov (0.1.
|
|
54
|
+
codecov (0.1.10)
|
|
54
55
|
json
|
|
55
56
|
simplecov
|
|
56
57
|
url
|
|
@@ -66,11 +67,11 @@ GEM
|
|
|
66
67
|
erubis (2.7.0)
|
|
67
68
|
ethon (0.10.1)
|
|
68
69
|
ffi (>= 1.3.0)
|
|
69
|
-
faraday (0.
|
|
70
|
+
faraday (0.12.0.1)
|
|
70
71
|
multipart-post (>= 1.2, < 3)
|
|
71
72
|
faraday_middleware (0.11.0.1)
|
|
72
73
|
faraday (>= 0.7.4, < 1.0)
|
|
73
|
-
ffi (1.9.
|
|
74
|
+
ffi (1.9.18)
|
|
74
75
|
fork (1.0.1)
|
|
75
76
|
fork_break (0.1.4)
|
|
76
77
|
fork (= 1.0.1)
|
|
@@ -174,12 +175,12 @@ GEM
|
|
|
174
175
|
ruby_dep (1.5.0)
|
|
175
176
|
safe_yaml (1.0.4)
|
|
176
177
|
shellany (0.0.1)
|
|
177
|
-
sidekiq (4.2.
|
|
178
|
+
sidekiq (4.2.10)
|
|
178
179
|
concurrent-ruby (~> 1.0)
|
|
179
180
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
180
181
|
rack-protection (>= 1.5.0)
|
|
181
182
|
redis (~> 3.2, >= 3.2.1)
|
|
182
|
-
simplecov (0.
|
|
183
|
+
simplecov (0.14.1)
|
|
183
184
|
docile (~> 1.1.0)
|
|
184
185
|
json (>= 1.8, < 3)
|
|
185
186
|
simplecov-html (~> 0.10.0)
|
|
@@ -201,7 +202,7 @@ GEM
|
|
|
201
202
|
polyglot (>= 0.3.1)
|
|
202
203
|
typhoeus (1.1.2)
|
|
203
204
|
ethon (>= 0.9.0)
|
|
204
|
-
tzinfo (0.3.
|
|
205
|
+
tzinfo (0.3.53)
|
|
205
206
|
url (0.3.2)
|
|
206
207
|
vegas (0.1.11)
|
|
207
208
|
rack (>= 1.0.0)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (2.
|
|
4
|
+
routemaster-drain (2.5.0)
|
|
5
|
+
addressable
|
|
5
6
|
concurrent-ruby
|
|
6
7
|
faraday (>= 0.9.0)
|
|
7
8
|
faraday_middleware
|
|
@@ -48,7 +49,7 @@ GEM
|
|
|
48
49
|
minitest (~> 5.1)
|
|
49
50
|
thread_safe (~> 0.3, >= 0.3.4)
|
|
50
51
|
tzinfo (~> 1.1)
|
|
51
|
-
addressable (2.5.
|
|
52
|
+
addressable (2.5.1)
|
|
52
53
|
public_suffix (~> 2.0, >= 2.0.2)
|
|
53
54
|
appraisal (2.1.0)
|
|
54
55
|
bundler
|
|
@@ -57,7 +58,7 @@ GEM
|
|
|
57
58
|
arel (6.0.4)
|
|
58
59
|
builder (3.2.3)
|
|
59
60
|
byebug (9.0.6)
|
|
60
|
-
codecov (0.1.
|
|
61
|
+
codecov (0.1.10)
|
|
61
62
|
json
|
|
62
63
|
simplecov
|
|
63
64
|
url
|
|
@@ -73,11 +74,11 @@ GEM
|
|
|
73
74
|
erubis (2.7.0)
|
|
74
75
|
ethon (0.10.1)
|
|
75
76
|
ffi (>= 1.3.0)
|
|
76
|
-
faraday (0.
|
|
77
|
+
faraday (0.12.0.1)
|
|
77
78
|
multipart-post (>= 1.2, < 3)
|
|
78
79
|
faraday_middleware (0.11.0.1)
|
|
79
80
|
faraday (>= 0.7.4, < 1.0)
|
|
80
|
-
ffi (1.9.
|
|
81
|
+
ffi (1.9.18)
|
|
81
82
|
fork (1.0.1)
|
|
82
83
|
fork_break (0.1.4)
|
|
83
84
|
fork (= 1.0.1)
|
|
@@ -121,7 +122,7 @@ GEM
|
|
|
121
122
|
multi_json (1.12.1)
|
|
122
123
|
multipart-post (2.0.0)
|
|
123
124
|
nenv (0.3.0)
|
|
124
|
-
nokogiri (1.7.
|
|
125
|
+
nokogiri (1.7.1)
|
|
125
126
|
mini_portile2 (~> 2.1.0)
|
|
126
127
|
notiffany (0.1.1)
|
|
127
128
|
nenv (~> 0.1)
|
|
@@ -190,12 +191,12 @@ GEM
|
|
|
190
191
|
ruby_dep (1.5.0)
|
|
191
192
|
safe_yaml (1.0.4)
|
|
192
193
|
shellany (0.0.1)
|
|
193
|
-
sidekiq (4.2.
|
|
194
|
+
sidekiq (4.2.10)
|
|
194
195
|
concurrent-ruby (~> 1.0)
|
|
195
196
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
196
197
|
rack-protection (>= 1.5.0)
|
|
197
198
|
redis (~> 3.2, >= 3.2.1)
|
|
198
|
-
simplecov (0.
|
|
199
|
+
simplecov (0.14.1)
|
|
199
200
|
docile (~> 1.1.0)
|
|
200
201
|
json (>= 1.8, < 3)
|
|
201
202
|
simplecov-html (~> 0.10.0)
|
|
@@ -214,10 +215,10 @@ GEM
|
|
|
214
215
|
sprockets (>= 3.0.0)
|
|
215
216
|
thor (0.19.4)
|
|
216
217
|
thread_safe (0.3.6)
|
|
217
|
-
tilt (2.0.
|
|
218
|
+
tilt (2.0.7)
|
|
218
219
|
typhoeus (1.1.2)
|
|
219
220
|
ethon (>= 0.9.0)
|
|
220
|
-
tzinfo (1.2.
|
|
221
|
+
tzinfo (1.2.3)
|
|
221
222
|
thread_safe (~> 0.1)
|
|
222
223
|
url (0.3.2)
|
|
223
224
|
vegas (0.1.11)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: ..
|
|
3
3
|
specs:
|
|
4
|
-
routemaster-drain (2.
|
|
4
|
+
routemaster-drain (2.5.0)
|
|
5
|
+
addressable
|
|
5
6
|
concurrent-ruby
|
|
6
7
|
faraday (>= 0.9.0)
|
|
7
8
|
faraday_middleware
|
|
@@ -14,44 +15,44 @@ PATH
|
|
|
14
15
|
GEM
|
|
15
16
|
remote: https://rubygems.org/
|
|
16
17
|
specs:
|
|
17
|
-
actioncable (5.0.
|
|
18
|
-
actionpack (= 5.0.
|
|
19
|
-
nio4r (
|
|
18
|
+
actioncable (5.0.2)
|
|
19
|
+
actionpack (= 5.0.2)
|
|
20
|
+
nio4r (>= 1.2, < 3.0)
|
|
20
21
|
websocket-driver (~> 0.6.1)
|
|
21
|
-
actionmailer (5.0.
|
|
22
|
-
actionpack (= 5.0.
|
|
23
|
-
actionview (= 5.0.
|
|
24
|
-
activejob (= 5.0.
|
|
22
|
+
actionmailer (5.0.2)
|
|
23
|
+
actionpack (= 5.0.2)
|
|
24
|
+
actionview (= 5.0.2)
|
|
25
|
+
activejob (= 5.0.2)
|
|
25
26
|
mail (~> 2.5, >= 2.5.4)
|
|
26
27
|
rails-dom-testing (~> 2.0)
|
|
27
|
-
actionpack (5.0.
|
|
28
|
-
actionview (= 5.0.
|
|
29
|
-
activesupport (= 5.0.
|
|
28
|
+
actionpack (5.0.2)
|
|
29
|
+
actionview (= 5.0.2)
|
|
30
|
+
activesupport (= 5.0.2)
|
|
30
31
|
rack (~> 2.0)
|
|
31
32
|
rack-test (~> 0.6.3)
|
|
32
33
|
rails-dom-testing (~> 2.0)
|
|
33
34
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
|
34
|
-
actionview (5.0.
|
|
35
|
-
activesupport (= 5.0.
|
|
35
|
+
actionview (5.0.2)
|
|
36
|
+
activesupport (= 5.0.2)
|
|
36
37
|
builder (~> 3.1)
|
|
37
38
|
erubis (~> 2.7.0)
|
|
38
39
|
rails-dom-testing (~> 2.0)
|
|
39
|
-
rails-html-sanitizer (~> 1.0, >= 1.0.
|
|
40
|
-
activejob (5.0.
|
|
41
|
-
activesupport (= 5.0.
|
|
40
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
|
41
|
+
activejob (5.0.2)
|
|
42
|
+
activesupport (= 5.0.2)
|
|
42
43
|
globalid (>= 0.3.6)
|
|
43
|
-
activemodel (5.0.
|
|
44
|
-
activesupport (= 5.0.
|
|
45
|
-
activerecord (5.0.
|
|
46
|
-
activemodel (= 5.0.
|
|
47
|
-
activesupport (= 5.0.
|
|
44
|
+
activemodel (5.0.2)
|
|
45
|
+
activesupport (= 5.0.2)
|
|
46
|
+
activerecord (5.0.2)
|
|
47
|
+
activemodel (= 5.0.2)
|
|
48
|
+
activesupport (= 5.0.2)
|
|
48
49
|
arel (~> 7.0)
|
|
49
|
-
activesupport (5.0.
|
|
50
|
+
activesupport (5.0.2)
|
|
50
51
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
51
52
|
i18n (~> 0.7)
|
|
52
53
|
minitest (~> 5.1)
|
|
53
54
|
tzinfo (~> 1.1)
|
|
54
|
-
addressable (2.5.
|
|
55
|
+
addressable (2.5.1)
|
|
55
56
|
public_suffix (~> 2.0, >= 2.0.2)
|
|
56
57
|
appraisal (2.1.0)
|
|
57
58
|
bundler
|
|
@@ -60,7 +61,7 @@ GEM
|
|
|
60
61
|
arel (7.1.4)
|
|
61
62
|
builder (3.2.3)
|
|
62
63
|
byebug (9.0.6)
|
|
63
|
-
codecov (0.1.
|
|
64
|
+
codecov (0.1.10)
|
|
64
65
|
json
|
|
65
66
|
simplecov
|
|
66
67
|
url
|
|
@@ -76,11 +77,11 @@ GEM
|
|
|
76
77
|
erubis (2.7.0)
|
|
77
78
|
ethon (0.10.1)
|
|
78
79
|
ffi (>= 1.3.0)
|
|
79
|
-
faraday (0.
|
|
80
|
+
faraday (0.12.0.1)
|
|
80
81
|
multipart-post (>= 1.2, < 3)
|
|
81
82
|
faraday_middleware (0.11.0.1)
|
|
82
83
|
faraday (>= 0.7.4, < 1.0)
|
|
83
|
-
ffi (1.9.
|
|
84
|
+
ffi (1.9.18)
|
|
84
85
|
fork (1.0.1)
|
|
85
86
|
fork_break (0.1.4)
|
|
86
87
|
fork (= 1.0.1)
|
|
@@ -124,8 +125,8 @@ GEM
|
|
|
124
125
|
multi_json (1.12.1)
|
|
125
126
|
multipart-post (2.0.0)
|
|
126
127
|
nenv (0.3.0)
|
|
127
|
-
nio4r (
|
|
128
|
-
nokogiri (1.7.
|
|
128
|
+
nio4r (2.0.0)
|
|
129
|
+
nokogiri (1.7.1)
|
|
129
130
|
mini_portile2 (~> 2.1.0)
|
|
130
131
|
notiffany (0.1.1)
|
|
131
132
|
nenv (~> 0.1)
|
|
@@ -141,26 +142,26 @@ GEM
|
|
|
141
142
|
rack
|
|
142
143
|
rack-test (0.6.3)
|
|
143
144
|
rack (>= 1.0)
|
|
144
|
-
rails (5.0.
|
|
145
|
-
actioncable (= 5.0.
|
|
146
|
-
actionmailer (= 5.0.
|
|
147
|
-
actionpack (= 5.0.
|
|
148
|
-
actionview (= 5.0.
|
|
149
|
-
activejob (= 5.0.
|
|
150
|
-
activemodel (= 5.0.
|
|
151
|
-
activerecord (= 5.0.
|
|
152
|
-
activesupport (= 5.0.
|
|
145
|
+
rails (5.0.2)
|
|
146
|
+
actioncable (= 5.0.2)
|
|
147
|
+
actionmailer (= 5.0.2)
|
|
148
|
+
actionpack (= 5.0.2)
|
|
149
|
+
actionview (= 5.0.2)
|
|
150
|
+
activejob (= 5.0.2)
|
|
151
|
+
activemodel (= 5.0.2)
|
|
152
|
+
activerecord (= 5.0.2)
|
|
153
|
+
activesupport (= 5.0.2)
|
|
153
154
|
bundler (>= 1.3.0, < 2.0)
|
|
154
|
-
railties (= 5.0.
|
|
155
|
+
railties (= 5.0.2)
|
|
155
156
|
sprockets-rails (>= 2.0.0)
|
|
156
157
|
rails-dom-testing (2.0.2)
|
|
157
158
|
activesupport (>= 4.2.0, < 6.0)
|
|
158
159
|
nokogiri (~> 1.6)
|
|
159
160
|
rails-html-sanitizer (1.0.3)
|
|
160
161
|
loofah (~> 2.0)
|
|
161
|
-
railties (5.0.
|
|
162
|
-
actionpack (= 5.0.
|
|
163
|
-
activesupport (= 5.0.
|
|
162
|
+
railties (5.0.2)
|
|
163
|
+
actionpack (= 5.0.2)
|
|
164
|
+
activesupport (= 5.0.2)
|
|
164
165
|
method_source
|
|
165
166
|
rake (>= 0.8.7)
|
|
166
167
|
thor (>= 0.18.1, < 2.0)
|
|
@@ -193,12 +194,12 @@ GEM
|
|
|
193
194
|
ruby_dep (1.5.0)
|
|
194
195
|
safe_yaml (1.0.4)
|
|
195
196
|
shellany (0.0.1)
|
|
196
|
-
sidekiq (4.2.
|
|
197
|
+
sidekiq (4.2.10)
|
|
197
198
|
concurrent-ruby (~> 1.0)
|
|
198
199
|
connection_pool (~> 2.2, >= 2.2.0)
|
|
199
200
|
rack-protection (>= 1.5.0)
|
|
200
201
|
redis (~> 3.2, >= 3.2.1)
|
|
201
|
-
simplecov (0.
|
|
202
|
+
simplecov (0.14.1)
|
|
202
203
|
docile (~> 1.1.0)
|
|
203
204
|
json (>= 1.8, < 3)
|
|
204
205
|
simplecov-html (~> 0.10.0)
|
|
@@ -217,7 +218,7 @@ GEM
|
|
|
217
218
|
thread_safe (0.3.6)
|
|
218
219
|
typhoeus (1.1.2)
|
|
219
220
|
ethon (>= 0.9.0)
|
|
220
|
-
tzinfo (1.2.
|
|
221
|
+
tzinfo (1.2.3)
|
|
221
222
|
thread_safe (~> 0.1)
|
|
222
223
|
url (0.3.2)
|
|
223
224
|
vegas (0.1.11)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
require 'routemaster/middleware/root_post_only'
|
|
2
|
+
require 'routemaster/middleware/authenticate'
|
|
3
|
+
require 'routemaster/middleware/parse'
|
|
4
|
+
require 'routemaster/middleware/expire_cache'
|
|
5
|
+
require 'routemaster/middleware/payload_filter'
|
|
6
|
+
require 'routemaster/middleware/filter'
|
|
7
|
+
require 'routemaster/drain/terminator'
|
|
8
|
+
require 'rack/builder'
|
|
9
|
+
require 'delegate'
|
|
10
|
+
|
|
11
|
+
module Routemaster
|
|
12
|
+
module Drain
|
|
13
|
+
# Rack application which authenticates, parses, filters duplicates in this request
|
|
14
|
+
# and invalidates the cache for all updated or new items.
|
|
15
|
+
#
|
|
16
|
+
# See the various corresponding middleware for details on operation:
|
|
17
|
+
# {Middleware::RootPostOnly}, {Middleware::Authenticate},
|
|
18
|
+
# {Middleware::Parse}, {Middleware::ExpireCache} and {Terminator}.
|
|
19
|
+
class CacheBusting
|
|
20
|
+
extend Forwardable
|
|
21
|
+
|
|
22
|
+
def initialize(options = {})
|
|
23
|
+
@terminator = terminator = Terminator.new
|
|
24
|
+
@app = ::Rack::Builder.new do
|
|
25
|
+
use Middleware::RootPostOnly
|
|
26
|
+
use Middleware::Authenticate, options
|
|
27
|
+
use Middleware::Parse
|
|
28
|
+
use Middleware::Filter, { filter: Routemaster::Middleware::PayloadFilter.new }.merge(options)
|
|
29
|
+
use Middleware::ExpireCache
|
|
30
|
+
run terminator
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
delegate :call => :@app
|
|
35
|
+
delegate [:on, :subscribe] => :@terminator
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
require 'routemaster/middleware/root_post_only'
|
|
2
2
|
require 'routemaster/middleware/authenticate'
|
|
3
3
|
require 'routemaster/middleware/parse'
|
|
4
|
+
require 'routemaster/middleware/siphon'
|
|
4
5
|
require 'routemaster/middleware/filter'
|
|
5
6
|
require 'routemaster/middleware/dirty'
|
|
6
7
|
require 'routemaster/middleware/cache'
|
|
8
|
+
require 'routemaster/middleware/expire_cache'
|
|
7
9
|
require 'routemaster/drain/terminator'
|
|
8
10
|
require 'rack/builder'
|
|
9
11
|
require 'delegate'
|
|
@@ -28,6 +30,8 @@ module Routemaster
|
|
|
28
30
|
use Middleware::RootPostOnly
|
|
29
31
|
use Middleware::Authenticate, options
|
|
30
32
|
use Middleware::Parse
|
|
33
|
+
use Middleware::ExpireCache, options
|
|
34
|
+
use Middleware::Siphon, options
|
|
31
35
|
use Middleware::Filter, options
|
|
32
36
|
use Middleware::Dirty, options
|
|
33
37
|
use Middleware::Cache, options
|
|
@@ -40,4 +44,3 @@ module Routemaster
|
|
|
40
44
|
end
|
|
41
45
|
end
|
|
42
46
|
end
|
|
43
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
require 'routemaster/middleware/root_post_only'
|
|
2
2
|
require 'routemaster/middleware/authenticate'
|
|
3
3
|
require 'routemaster/middleware/parse'
|
|
4
|
+
require 'routemaster/middleware/siphon'
|
|
4
5
|
require 'routemaster/middleware/filter'
|
|
5
6
|
require 'routemaster/middleware/dirty'
|
|
6
7
|
require 'routemaster/drain/terminator'
|
|
@@ -29,6 +30,7 @@ module Routemaster
|
|
|
29
30
|
use Middleware::RootPostOnly
|
|
30
31
|
use Middleware::Authenticate, options
|
|
31
32
|
use Middleware::Parse
|
|
33
|
+
use Middleware::Siphon, options
|
|
32
34
|
use Middleware::Filter, options
|
|
33
35
|
use Middleware::Dirty, options
|
|
34
36
|
run terminator
|
|
@@ -40,4 +42,3 @@ module Routemaster
|
|
|
40
42
|
end
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
|
-
|
data/lib/routemaster/drain.rb
CHANGED
|
@@ -17,7 +17,7 @@ module Routemaster
|
|
|
17
17
|
include Wisper::Publisher
|
|
18
18
|
|
|
19
19
|
# @param uuid [Enumerable] a set of accepted authentication tokens
|
|
20
|
-
def initialize(app, uuid: nil)
|
|
20
|
+
def initialize(app, uuid: nil, **_)
|
|
21
21
|
@app = app
|
|
22
22
|
@uuid = uuid || Config.drain_tokens
|
|
23
23
|
|
|
@@ -56,4 +56,3 @@ module Routemaster
|
|
|
56
56
|
end
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
|
-
|
|
@@ -7,7 +7,7 @@ require 'routemaster/event_index'
|
|
|
7
7
|
module Routemaster
|
|
8
8
|
module Middleware
|
|
9
9
|
class Cache
|
|
10
|
-
def initialize(app, cache:nil, client:nil, queue:nil)
|
|
10
|
+
def initialize(app, cache:nil, client:nil, queue:nil, **_)
|
|
11
11
|
@app = app
|
|
12
12
|
@cache = cache || Routemaster::Cache.new
|
|
13
13
|
@client = client || Routemaster::Jobs::Client.new
|
|
@@ -16,7 +16,6 @@ module Routemaster
|
|
|
16
16
|
|
|
17
17
|
def call(env)
|
|
18
18
|
env.fetch('routemaster.dirty', []).each do |url|
|
|
19
|
-
@cache.invalidate(url)
|
|
20
19
|
@client.enqueue(@queue, Routemaster::Jobs::CacheAndSweep, url)
|
|
21
20
|
end
|
|
22
21
|
@app.call(env)
|
|
@@ -11,7 +11,7 @@ module Routemaster
|
|
|
11
11
|
# The dirty map is passed as `:map` to the constructor and must respond to
|
|
12
12
|
# `#mark` (like `Routemaster::Dirty::Map`).
|
|
13
13
|
class Dirty
|
|
14
|
-
def initialize(app, dirty_map:nil)
|
|
14
|
+
def initialize(app, dirty_map: nil, **_)
|
|
15
15
|
@app = app
|
|
16
16
|
@map = dirty_map || Routemaster::Dirty::Map.new
|
|
17
17
|
end
|
|
@@ -28,6 +28,3 @@ module Routemaster
|
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'routemaster/cache'
|
|
2
|
+
|
|
3
|
+
module Routemaster
|
|
4
|
+
module Middleware
|
|
5
|
+
class ExpireCache
|
|
6
|
+
def initialize(app, cache:nil, **_)
|
|
7
|
+
@app = app
|
|
8
|
+
@cache = cache || Routemaster::Cache.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def call(env)
|
|
12
|
+
env.fetch('routemaster.payload', []).each do |event|
|
|
13
|
+
next if event['type'] == 'noop'
|
|
14
|
+
@cache.invalidate(event['url'])
|
|
15
|
+
end
|
|
16
|
+
@app.call(env)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -9,7 +9,7 @@ module Routemaster
|
|
|
9
9
|
class Filter
|
|
10
10
|
# @param filter [Routemaster::Dirty::Filter] an event filter (optional;
|
|
11
11
|
# will be created using the `redis` and `expiry` options if not provided)
|
|
12
|
-
def initialize(app, filter:nil)
|
|
12
|
+
def initialize(app, filter:nil, **_)
|
|
13
13
|
@app = app
|
|
14
14
|
@filter = filter || Routemaster::Dirty::Filter.new
|
|
15
15
|
end
|
|
@@ -19,7 +19,7 @@ module Routemaster
|
|
|
19
19
|
if payload && payload.any?
|
|
20
20
|
env['routemaster.payload'] = @filter.run(payload)
|
|
21
21
|
end
|
|
22
|
-
@app.call(env)
|
|
22
|
+
@app.call(env)
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
module Routemaster
|
|
2
|
+
module Middleware
|
|
3
|
+
class PayloadFilter
|
|
4
|
+
# Filters duplicate events by url and type in a single payload.
|
|
5
|
+
def run(payload)
|
|
6
|
+
payload.group_by { |event| [event['url'], event['type']] }.map { |_, events| events.last }
|
|
7
|
+
end
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Routemaster
|
|
2
|
+
module Middleware
|
|
3
|
+
# Filters out events based on their topic and passes them to a handling class
|
|
4
|
+
#
|
|
5
|
+
# `use Middleware::Siphon, 'some_topic' => SomeTopicHandler`
|
|
6
|
+
#
|
|
7
|
+
# Topic handlers are initialized with the full event payload and must respond to `#call`
|
|
8
|
+
class Siphon
|
|
9
|
+
def initialize(app, siphon_events: nil)
|
|
10
|
+
@app = app
|
|
11
|
+
@processors = siphon_events || {}
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def call(env)
|
|
15
|
+
siphoned, non_siphoned = env.fetch('routemaster.payload', []).partition do |event|
|
|
16
|
+
topics_to_siphon.include? event['topic']
|
|
17
|
+
end
|
|
18
|
+
siphoned.each do |event|
|
|
19
|
+
@processors[event['topic']].new(event).call
|
|
20
|
+
end
|
|
21
|
+
env['routemaster.payload'] = non_siphoned
|
|
22
|
+
@app.call(env)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def topics_to_siphon
|
|
28
|
+
@topics_to_siphon ||= @processors.keys.map(&:to_s)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
require 'addressable/template'
|
|
2
|
+
|
|
1
3
|
require 'routemaster/api_client'
|
|
2
4
|
require 'routemaster/responses/hateoas_enumerable_response'
|
|
3
5
|
require 'routemaster/responses/hateoas_response'
|
|
@@ -5,40 +7,48 @@ require 'routemaster/responses/hateoas_response'
|
|
|
5
7
|
module Routemaster
|
|
6
8
|
module Resources
|
|
7
9
|
class RestResource
|
|
8
|
-
attr_reader :url
|
|
9
|
-
|
|
10
10
|
def initialize(url, client: nil)
|
|
11
|
-
@
|
|
11
|
+
@url_template = Addressable::Template.new(url)
|
|
12
12
|
@client = client || Routemaster::APIClient.new
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def create(params)
|
|
16
16
|
@client.with_response(Responses::HateoasResponse) do
|
|
17
|
-
@client.post(
|
|
17
|
+
@client.post(expanded_url, body: params)
|
|
18
18
|
end
|
|
19
19
|
end
|
|
20
20
|
|
|
21
21
|
def show(id=nil, enable_caching: true)
|
|
22
22
|
@client.with_response(Responses::HateoasResponse) do
|
|
23
|
-
@client.get(
|
|
23
|
+
@client.get(expanded_url(id: id), options: { enable_caching: enable_caching })
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def index(params: {}, filters: {}, enable_caching: false)
|
|
28
28
|
@client.with_response(Responses::HateoasEnumerableResponse) do
|
|
29
|
-
@client.get(
|
|
29
|
+
@client.get(expanded_url, params: params.merge(filters), options: { enable_caching: enable_caching })
|
|
30
30
|
end
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
def update(id=nil, params)
|
|
34
34
|
@client.with_response(Responses::HateoasResponse) do
|
|
35
|
-
@client.patch(
|
|
35
|
+
@client.patch(expanded_url(id: id), body: params)
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
38
|
|
|
39
39
|
def destroy(id=nil)
|
|
40
40
|
# no response wrapping as DELETE is supposed to 204.
|
|
41
|
-
@client.delete(
|
|
41
|
+
@client.delete(expanded_url(id: id))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def url
|
|
45
|
+
@url_template.pattern
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def expanded_url(**params)
|
|
51
|
+
@url_template.expand(params).to_s
|
|
42
52
|
end
|
|
43
53
|
end
|
|
44
54
|
end
|
data/routemaster-drain.gemspec
CHANGED
|
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
|
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^spec/})
|
|
17
17
|
spec.require_paths = %w(lib)
|
|
18
18
|
|
|
19
|
+
spec.add_runtime_dependency 'addressable'
|
|
19
20
|
spec.add_runtime_dependency 'faraday', '>= 0.9.0'
|
|
20
21
|
spec.add_runtime_dependency 'faraday_middleware'
|
|
21
22
|
spec.add_runtime_dependency 'typhoeus', '~> 1.1'
|
|
@@ -111,12 +111,7 @@ describe Routemaster::APIClient do
|
|
|
111
111
|
end
|
|
112
112
|
|
|
113
113
|
let(:callback){
|
|
114
|
-
subject.on_success
|
|
115
|
-
callback_spy.success
|
|
116
|
-
end
|
|
117
|
-
subject.on_error do
|
|
118
|
-
callback_spy.error
|
|
119
|
-
end
|
|
114
|
+
subject.on_success { callback_spy.success }.zip(subject.on_error { callback_spy.error })
|
|
120
115
|
}
|
|
121
116
|
|
|
122
117
|
context "when successful" do
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec/support/rack_test'
|
|
3
|
+
require 'spec/support/uses_redis'
|
|
4
|
+
require 'spec/support/uses_dotenv'
|
|
5
|
+
require 'spec/support/events'
|
|
6
|
+
require 'routemaster/drain/cache_busting'
|
|
7
|
+
require 'json'
|
|
8
|
+
|
|
9
|
+
describe Routemaster::Drain::CacheBusting do
|
|
10
|
+
uses_dotenv
|
|
11
|
+
uses_redis
|
|
12
|
+
|
|
13
|
+
let(:app) { described_class.new }
|
|
14
|
+
let(:listener) { double 'listener' }
|
|
15
|
+
|
|
16
|
+
before { app.subscribe(listener, prefix: true) }
|
|
17
|
+
|
|
18
|
+
let(:path) { '/' }
|
|
19
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }.to_json }
|
|
20
|
+
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
|
21
|
+
let(:perform) { post path, payload, environment }
|
|
22
|
+
|
|
23
|
+
before { authorize 'd3m0', 'x' }
|
|
24
|
+
|
|
25
|
+
it 'succeeds' do
|
|
26
|
+
perform
|
|
27
|
+
expect(last_response.status).to eq(204)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
it 'emits events' do
|
|
31
|
+
expect(listener).to receive(:on_events_received) do |payload|
|
|
32
|
+
expect(payload.size).to eq(3)
|
|
33
|
+
end
|
|
34
|
+
perform
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'increments the event index' do
|
|
38
|
+
ei_double = double(increment: 1)
|
|
39
|
+
allow(Routemaster::EventIndex).to receive(:new).and_return(ei_double)
|
|
40
|
+
expect(ei_double).to receive(:increment).exactly(3).times
|
|
41
|
+
perform
|
|
42
|
+
end
|
|
43
|
+
end
|
|
@@ -3,25 +3,31 @@ require 'spec/support/rack_test'
|
|
|
3
3
|
require 'spec/support/uses_redis'
|
|
4
4
|
require 'spec/support/uses_dotenv'
|
|
5
5
|
require 'spec/support/events'
|
|
6
|
+
require 'spec/support/siphon'
|
|
7
|
+
|
|
6
8
|
require 'routemaster/drain/caching'
|
|
9
|
+
|
|
7
10
|
require 'json'
|
|
8
11
|
|
|
9
12
|
describe Routemaster::Drain::Caching do
|
|
10
13
|
uses_dotenv
|
|
11
14
|
uses_redis
|
|
12
15
|
|
|
13
|
-
let(:app) { described_class.new }
|
|
16
|
+
let(:app) { described_class.new options}
|
|
14
17
|
let(:listener) { double 'listener' }
|
|
18
|
+
let(:options) { {} }
|
|
15
19
|
|
|
16
20
|
before { app.subscribe(listener, prefix: true) }
|
|
17
21
|
|
|
18
22
|
let(:path) { '/' }
|
|
19
|
-
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }
|
|
23
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) } }
|
|
20
24
|
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
|
21
|
-
let(:perform) { post path, payload, environment }
|
|
25
|
+
let(:perform) { post path, payload.to_json, environment }
|
|
22
26
|
|
|
23
27
|
before { authorize 'd3m0', 'x' }
|
|
24
28
|
|
|
29
|
+
include_examples 'supports siphon'
|
|
30
|
+
|
|
25
31
|
it 'succeeds' do
|
|
26
32
|
perform
|
|
27
33
|
expect(last_response.status).to eq(204)
|
|
@@ -37,7 +43,7 @@ describe Routemaster::Drain::Caching do
|
|
|
37
43
|
it 'increments the event index' do
|
|
38
44
|
ei_double = double(increment: 1)
|
|
39
45
|
allow(Routemaster::EventIndex).to receive(:new).and_return(ei_double)
|
|
40
|
-
expect(ei_double).to receive(:increment).exactly(
|
|
46
|
+
expect(ei_double).to receive(:increment).exactly(4).times
|
|
41
47
|
perform
|
|
42
48
|
end
|
|
43
49
|
|
|
@@ -3,6 +3,7 @@ require 'spec/support/rack_test'
|
|
|
3
3
|
require 'spec/support/uses_redis'
|
|
4
4
|
require 'spec/support/uses_dotenv'
|
|
5
5
|
require 'spec/support/events'
|
|
6
|
+
require 'spec/support/siphon'
|
|
6
7
|
require 'routemaster/drain/mapping'
|
|
7
8
|
require 'json'
|
|
8
9
|
|
|
@@ -10,18 +11,21 @@ describe Routemaster::Drain::Mapping do
|
|
|
10
11
|
uses_dotenv
|
|
11
12
|
uses_redis
|
|
12
13
|
|
|
13
|
-
let(:app) { described_class.new }
|
|
14
|
+
let(:app) { described_class.new(options) }
|
|
15
|
+
let(:options) { {} }
|
|
14
16
|
let(:listener) { double 'listener' }
|
|
15
|
-
|
|
17
|
+
|
|
16
18
|
before { app.subscribe(listener, prefix: true) }
|
|
17
19
|
|
|
18
20
|
let(:path) { '/' }
|
|
19
|
-
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) }
|
|
21
|
+
let(:payload) { [1,2,3,1].map { |idx| make_event(idx) } }
|
|
20
22
|
let(:environment) {{ 'CONTENT_TYPE' => 'application/json' }}
|
|
21
|
-
let(:perform) { post path, payload, environment }
|
|
23
|
+
let(:perform) { post path, payload.to_json, environment }
|
|
22
24
|
|
|
23
25
|
before { authorize 'd3m0', 'x' }
|
|
24
26
|
|
|
27
|
+
include_examples 'supports siphon'
|
|
28
|
+
|
|
25
29
|
it 'succeeds' do
|
|
26
30
|
perform
|
|
27
31
|
expect(last_response.status).to eq(204)
|
|
@@ -35,11 +39,11 @@ describe Routemaster::Drain::Mapping do
|
|
|
35
39
|
end
|
|
36
40
|
|
|
37
41
|
let(:map) { Routemaster::Dirty::Map.new }
|
|
38
|
-
|
|
42
|
+
|
|
39
43
|
it 'uses dirty map' do
|
|
40
44
|
payload1 = [1,2,3,1].map { |idx| make_event(idx) }.to_json
|
|
41
45
|
payload2 = [1,4,5,2].map { |idx| make_event(idx) }.to_json
|
|
42
|
-
|
|
46
|
+
|
|
43
47
|
post path, payload1, environment
|
|
44
48
|
expect(map.count).to eq(3)
|
|
45
49
|
map.sweep_one("https://example.com/stuff/1") { true }
|
|
@@ -48,4 +52,3 @@ describe Routemaster::Drain::Mapping do
|
|
|
48
52
|
expect(map.count).to eq(4) # 2, 3, 4, 5 (1 is a repeat event, filtered out)
|
|
49
53
|
end
|
|
50
54
|
end
|
|
51
|
-
|
|
@@ -19,11 +19,6 @@ RSpec.describe Routemaster::Middleware::Cache do
|
|
|
19
19
|
describe '#call' do
|
|
20
20
|
let(:payload) { ['https://example.com/1'] }
|
|
21
21
|
|
|
22
|
-
it 'increments the event_index' do
|
|
23
|
-
expect(cache).to receive(:invalidate)
|
|
24
|
-
perform
|
|
25
|
-
end
|
|
26
|
-
|
|
27
22
|
it 'queues a fetch job' do
|
|
28
23
|
expect(client).to receive(:enqueue).with('routemaster', Routemaster::Jobs::CacheAndSweep, 'https://example.com/1')
|
|
29
24
|
perform
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'spec/support/rack_test'
|
|
3
|
+
require 'spec/support/events'
|
|
4
|
+
require 'routemaster/middleware/siphon'
|
|
5
|
+
require 'json'
|
|
6
|
+
|
|
7
|
+
describe Routemaster::Middleware::Siphon do
|
|
8
|
+
let(:terminator) { ErrorRackApp.new }
|
|
9
|
+
let(:app) { described_class.new(terminator, options) }
|
|
10
|
+
|
|
11
|
+
let(:perform) do
|
|
12
|
+
post '/whatever', '', 'routemaster.payload' => payload
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
describe '#call' do
|
|
16
|
+
|
|
17
|
+
let(:options) { { filter:filter } }
|
|
18
|
+
let(:payload) { [ make_event(1), make_event(1).merge({'topic' => 'notstuff'})] }
|
|
19
|
+
|
|
20
|
+
context "if no siphon is defined" do
|
|
21
|
+
let(:options) { {} }
|
|
22
|
+
|
|
23
|
+
it "passes all to the terminator" do
|
|
24
|
+
perform
|
|
25
|
+
expect(terminator.last_env['routemaster.payload']).to eq payload
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context "if a 'stuff' siphon is defined" do
|
|
30
|
+
let(:siphon_double) { double(new: siphon_instance) }
|
|
31
|
+
let(:siphon_instance) { double(call: nil) }
|
|
32
|
+
let(:options) { { siphon_events: { 'stuff' => siphon_double } } }
|
|
33
|
+
|
|
34
|
+
it "calls the siphon with the event" do
|
|
35
|
+
perform
|
|
36
|
+
expect(siphon_double).to have_received(:new).with(payload[0])
|
|
37
|
+
expect(siphon_instance).to have_received(:call)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "passes 'notstuff' to the terminator" do
|
|
41
|
+
perform
|
|
42
|
+
expect(terminator.last_env['routemaster.payload']).to eq [payload[1]]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -4,46 +4,55 @@ require 'routemaster/resources/rest_resource'
|
|
|
4
4
|
module Routemaster
|
|
5
5
|
module Resources
|
|
6
6
|
RSpec.describe RestResource do
|
|
7
|
-
let(:url) { 'test_url' }
|
|
8
7
|
let(:client) { double('Client') }
|
|
9
8
|
let(:params) { {} }
|
|
10
9
|
|
|
11
|
-
subject { described_class.new(url, client: client) }
|
|
12
|
-
|
|
13
10
|
before { allow(client).to receive(:with_response).and_yield }
|
|
14
11
|
|
|
15
|
-
describe
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
describe "singular resource" do
|
|
13
|
+
let(:url) { '/resources/1' }
|
|
14
|
+
|
|
15
|
+
subject { described_class.new('/resources/{id}', client: client) }
|
|
16
|
+
|
|
17
|
+
describe '#show' do
|
|
18
|
+
it 'gets to the given url' do
|
|
19
|
+
expect(client).to receive(:get).with(url, options: { enable_caching: true })
|
|
20
|
+
subject.show(1)
|
|
21
|
+
end
|
|
19
22
|
end
|
|
20
|
-
end
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
describe '#update' do
|
|
25
|
+
it 'updates the given resource' do
|
|
26
|
+
expect(client).to receive(:patch).with(url, body: params)
|
|
27
|
+
subject.update(1, params)
|
|
28
|
+
end
|
|
26
29
|
end
|
|
27
|
-
end
|
|
28
30
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
describe '#destroy' do
|
|
32
|
+
it 'destroys the given resource' do
|
|
33
|
+
expect(client).to receive(:delete).with(url)
|
|
34
|
+
subject.destroy(1)
|
|
35
|
+
end
|
|
33
36
|
end
|
|
34
37
|
end
|
|
35
38
|
|
|
36
|
-
describe
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
describe "collection resource" do
|
|
40
|
+
let(:url) { '/resources' }
|
|
41
|
+
|
|
42
|
+
subject { described_class.new('/resources{?page,per_page}', client: client) }
|
|
43
|
+
|
|
44
|
+
describe '#create' do
|
|
45
|
+
it 'posts to the given url' do
|
|
46
|
+
expect(client).to receive(:post).with(url, body: params)
|
|
47
|
+
subject.create(params)
|
|
48
|
+
end
|
|
40
49
|
end
|
|
41
|
-
end
|
|
42
50
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
describe '#index' do
|
|
52
|
+
it 'gets to the given url' do
|
|
53
|
+
expect(client).to receive(:get).with(url, params: {}, options: { enable_caching: false })
|
|
54
|
+
subject.index
|
|
55
|
+
end
|
|
47
56
|
end
|
|
48
57
|
end
|
|
49
58
|
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
RSpec.shared_examples 'supports siphon' do
|
|
2
|
+
context "if a siphon is defined" do
|
|
3
|
+
let(:siphon_double) { double(new: siphon_instance) }
|
|
4
|
+
let(:siphon_instance) { double(call: nil) }
|
|
5
|
+
let(:options){ { siphon_events: { payload[0]['topic'] => siphon_double } } }
|
|
6
|
+
|
|
7
|
+
it "calls the siphon with the event" do
|
|
8
|
+
perform
|
|
9
|
+
expect(siphon_double).to have_received(:new).with(payload[0]).at_least(:once)
|
|
10
|
+
expect(siphon_instance).to have_received(:call).at_least(:once)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: routemaster-drain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.5.0
|
|
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-04-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: addressable
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '0'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '0'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: faraday
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -164,6 +178,7 @@ files:
|
|
|
164
178
|
- lib/routemaster/dirty/state.rb
|
|
165
179
|
- lib/routemaster/drain.rb
|
|
166
180
|
- lib/routemaster/drain/basic.rb
|
|
181
|
+
- lib/routemaster/drain/cache_busting.rb
|
|
167
182
|
- lib/routemaster/drain/caching.rb
|
|
168
183
|
- lib/routemaster/drain/mapping.rb
|
|
169
184
|
- lib/routemaster/drain/terminator.rb
|
|
@@ -180,11 +195,14 @@ files:
|
|
|
180
195
|
- lib/routemaster/middleware/cache.rb
|
|
181
196
|
- lib/routemaster/middleware/dirty.rb
|
|
182
197
|
- lib/routemaster/middleware/error_handling.rb
|
|
198
|
+
- lib/routemaster/middleware/expire_cache.rb
|
|
183
199
|
- lib/routemaster/middleware/filter.rb
|
|
184
200
|
- lib/routemaster/middleware/metrics.rb
|
|
185
201
|
- lib/routemaster/middleware/parse.rb
|
|
202
|
+
- lib/routemaster/middleware/payload_filter.rb
|
|
186
203
|
- lib/routemaster/middleware/response_caching.rb
|
|
187
204
|
- lib/routemaster/middleware/root_post_only.rb
|
|
205
|
+
- lib/routemaster/middleware/siphon.rb
|
|
188
206
|
- lib/routemaster/null_logger.rb
|
|
189
207
|
- lib/routemaster/redis_broker.rb
|
|
190
208
|
- lib/routemaster/resources/rest_resource.rb
|
|
@@ -198,6 +216,7 @@ files:
|
|
|
198
216
|
- spec/routemaster/dirty/map_spec.rb
|
|
199
217
|
- spec/routemaster/dirty/state_spec.rb
|
|
200
218
|
- spec/routemaster/drain/basic_spec.rb
|
|
219
|
+
- spec/routemaster/drain/cache_busting_spec.rb
|
|
201
220
|
- spec/routemaster/drain/caching_spec.rb
|
|
202
221
|
- spec/routemaster/drain/mapping_spec.rb
|
|
203
222
|
- spec/routemaster/drain/terminator_spec.rb
|
|
@@ -214,6 +233,7 @@ files:
|
|
|
214
233
|
- spec/routemaster/middleware/filter_spec.rb
|
|
215
234
|
- spec/routemaster/middleware/parse_spec.rb
|
|
216
235
|
- spec/routemaster/middleware/root_post_only_spec.rb
|
|
236
|
+
- spec/routemaster/middleware/siphon_spec.rb
|
|
217
237
|
- spec/routemaster/redis_broker_spec.rb
|
|
218
238
|
- spec/routemaster/resources/rest_resource_spec.rb
|
|
219
239
|
- spec/routemaster/responses/hateoas_enumerable_response_spec.rb
|
|
@@ -224,6 +244,7 @@ files:
|
|
|
224
244
|
- spec/support/events.rb
|
|
225
245
|
- spec/support/rack_test.rb
|
|
226
246
|
- spec/support/server.rb
|
|
247
|
+
- spec/support/siphon.rb
|
|
227
248
|
- spec/support/uses_dotenv.rb
|
|
228
249
|
- spec/support/uses_redis.rb
|
|
229
250
|
- spec/support/uses_webmock.rb
|
|
@@ -258,6 +279,7 @@ test_files:
|
|
|
258
279
|
- spec/routemaster/dirty/map_spec.rb
|
|
259
280
|
- spec/routemaster/dirty/state_spec.rb
|
|
260
281
|
- spec/routemaster/drain/basic_spec.rb
|
|
282
|
+
- spec/routemaster/drain/cache_busting_spec.rb
|
|
261
283
|
- spec/routemaster/drain/caching_spec.rb
|
|
262
284
|
- spec/routemaster/drain/mapping_spec.rb
|
|
263
285
|
- spec/routemaster/drain/terminator_spec.rb
|
|
@@ -274,6 +296,7 @@ test_files:
|
|
|
274
296
|
- spec/routemaster/middleware/filter_spec.rb
|
|
275
297
|
- spec/routemaster/middleware/parse_spec.rb
|
|
276
298
|
- spec/routemaster/middleware/root_post_only_spec.rb
|
|
299
|
+
- spec/routemaster/middleware/siphon_spec.rb
|
|
277
300
|
- spec/routemaster/redis_broker_spec.rb
|
|
278
301
|
- spec/routemaster/resources/rest_resource_spec.rb
|
|
279
302
|
- spec/routemaster/responses/hateoas_enumerable_response_spec.rb
|
|
@@ -284,6 +307,7 @@ test_files:
|
|
|
284
307
|
- spec/support/events.rb
|
|
285
308
|
- spec/support/rack_test.rb
|
|
286
309
|
- spec/support/server.rb
|
|
310
|
+
- spec/support/siphon.rb
|
|
287
311
|
- spec/support/uses_dotenv.rb
|
|
288
312
|
- spec/support/uses_redis.rb
|
|
289
313
|
- spec/support/uses_webmock.rb
|