routemaster-drain 2.5.2 → 2.5.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG.md +7 -0
- data/Gemfile.lock +1 -1
- data/README.md +34 -6
- data/gemfiles/rails_3.gemfile.lock +1 -1
- data/gemfiles/rails_4.gemfile.lock +1 -1
- data/gemfiles/rails_5.gemfile.lock +1 -1
- data/lib/routemaster/config.rb +2 -2
- data/lib/routemaster/drain.rb +1 -1
- data/lib/routemaster/middleware/siphon.rb +1 -1
- data/lib/routemaster/redis_broker.rb +29 -3
- data/spec/routemaster/redis_broker_spec.rb +26 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c1bac015db93c186bc55017d7da1eb6534dc550
|
4
|
+
data.tar.gz: d92592efc2519f971cad96b05bb20d830ec8de82
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 624d4c43c9482d39eb91b3b14fa6972f31f33ab8597b0bf1c5d98a31ec2753d67f5345e3fe4f56c81eb4ebdc0e39a6d0b0db4c322e266291949a26cbb0e86bf5
|
7
|
+
data.tar.gz: 368f7edb6b89b17d32ff5ce94bfe0d089d0cebb9269123fe6fd89b6f1d8871319a3c28e491206dd663fb071effa670bf5a09b878882ca69f5b5b31645bbe8aef
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -36,7 +36,7 @@ Add this line to your application's Gemfile:
|
|
36
36
|
|
37
37
|
gem 'routemaster-drain'
|
38
38
|
|
39
|
-
|
39
|
+
### Configuration
|
40
40
|
|
41
41
|
This gem is configured through the environment, making 12factor compliance
|
42
42
|
easier.
|
@@ -66,6 +66,17 @@ Optional:
|
|
66
66
|
- `ROUTEMASTER_CACHE_TIMEOUT`: if using the cache, how long before Faraday will timeout fetching the resource. Defaults to 1 second.
|
67
67
|
- `ROUTEMASTER_CACHE_VERIFY_SSL`: if using the cache, whether to verify SSL when fetching the resource. Defaults to false.
|
68
68
|
|
69
|
+
Alternatively, it's possible to configure the gem to use pre-initialized Redis clients for the Cache Redis, the Drain Redis, or both.
|
70
|
+
|
71
|
+
The clients are expected to be instances of `Redis::Distributed`. When configured, the pre-built clients take precendence and the gem won't try to estabilish its own private connection to the Redis instances supplied in the ENV variables. This is helpful if you want to re-use connections in order to reduce the number of connected clients to your Redis servers.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
Routemaster::RedisBroker.instance.inject(
|
75
|
+
drain_redis: a_redis_object,
|
76
|
+
cache_redis: another_redis_object
|
77
|
+
)
|
78
|
+
```
|
79
|
+
|
69
80
|
## Illustrated use cases
|
70
81
|
|
71
82
|
|
@@ -177,7 +188,7 @@ cache as events are received.
|
|
177
188
|
For this purpose, use `Routemaster::Drain::Caching`:
|
178
189
|
|
179
190
|
```ruby
|
180
|
-
require 'routemaster/drain/
|
191
|
+
require 'routemaster/drain/caching'
|
181
192
|
$app = Routemaster::Drain::Caching.new
|
182
193
|
```
|
183
194
|
|
@@ -188,7 +199,7 @@ And mount it as usual:
|
|
188
199
|
map('/events') { run $app }
|
189
200
|
```
|
190
201
|
|
191
|
-
You can still attach a
|
202
|
+
You can still attach a listener if you want the incoming events. Typically,
|
192
203
|
what you'll want is the cache:
|
193
204
|
|
194
205
|
```ruby
|
@@ -206,18 +217,35 @@ whenever the drain gets notified about a change on that widget.
|
|
206
217
|
Note that `Cache#fget` is a future, so you can efficiently query many resources
|
207
218
|
and have any `HTTP GET` requests (and cache queries) happen in parallel.
|
208
219
|
|
220
|
+
Resources are fetched through jobs. By default it uses Resque but can be changed
|
221
|
+
to use Sidekiq.
|
222
|
+
|
223
|
+
```
|
224
|
+
ROUTEMASTER_QUEUE_ADAPTER=sidekiq
|
225
|
+
```
|
226
|
+
|
227
|
+
Finally do not forget the corresponding backend:
|
228
|
+
```
|
229
|
+
# config/initializers/...
|
230
|
+
|
231
|
+
require 'routemaster/jobs/backends/sidekiq'
|
232
|
+
# or
|
233
|
+
require 'routemaster/jobs/backends/resque'
|
234
|
+
```
|
235
|
+
|
236
|
+
|
209
237
|
See
|
210
238
|
[rubydoc](http://rubydoc.info/github/deliveroo/routemaster-drain/Routemaster/Cache)
|
211
239
|
for more details on `Cache`.
|
212
240
|
|
213
241
|
### Expire Cache data for all notified resources
|
214
242
|
|
215
|
-
You may wish to maintain a coherent cache but don't need the cache to be warmed
|
243
|
+
You may wish to maintain a coherent cache, but don't need the cache to be warmed
|
216
244
|
before you process incoming events. In that case, use the cache as detailed above
|
217
|
-
but swap the `Caching` drain out for `
|
245
|
+
but swap the `Caching` drain out for `CacheBusting`
|
218
246
|
|
219
247
|
```ruby
|
220
|
-
require 'routemaster/drain/
|
248
|
+
require 'routemaster/drain/caching_busting'
|
221
249
|
$app = Routemaster::Drain::CachingBusting.new
|
222
250
|
```
|
223
251
|
|
data/lib/routemaster/config.rb
CHANGED
@@ -25,11 +25,11 @@ module Routemaster
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def drain_redis
|
28
|
-
RedisBroker.instance.get(:drain_redis, urls: ENV.fetch('ROUTEMASTER_DRAIN_REDIS').split(','))
|
28
|
+
RedisBroker.instance.get(:drain_redis, urls: ENV.fetch('ROUTEMASTER_DRAIN_REDIS', '').split(','))
|
29
29
|
end
|
30
30
|
|
31
31
|
def cache_redis
|
32
|
-
RedisBroker.instance.get(:cache_redis, urls: ENV.fetch('ROUTEMASTER_CACHE_REDIS').split(','))
|
32
|
+
RedisBroker.instance.get(:cache_redis, urls: ENV.fetch('ROUTEMASTER_CACHE_REDIS', '').split(','))
|
33
33
|
end
|
34
34
|
|
35
35
|
#
|
data/lib/routemaster/drain.rb
CHANGED
@@ -2,7 +2,7 @@ module Routemaster
|
|
2
2
|
module Middleware
|
3
3
|
# Filters out events based on their topic and passes them to a handling class
|
4
4
|
#
|
5
|
-
# `use Middleware::Siphon, 'some_topic' => SomeTopicHandler`
|
5
|
+
# `use Middleware::Siphon, 'siphon_events' => {'some_topic' => SomeTopicHandler`}
|
6
6
|
#
|
7
7
|
# Topic handlers are initialized with the full event payload and must respond to `#call`
|
8
8
|
class Siphon
|
@@ -7,6 +7,8 @@ module Routemaster
|
|
7
7
|
class RedisBroker
|
8
8
|
include Singleton
|
9
9
|
|
10
|
+
DEFAULT_NAMESPACE = 'rm'.freeze
|
11
|
+
|
10
12
|
def initialize
|
11
13
|
@_connections = {}
|
12
14
|
_cleanup
|
@@ -16,7 +18,7 @@ module Routemaster
|
|
16
18
|
_check_for_fork
|
17
19
|
@_connections[name] ||= begin
|
18
20
|
parsed_url = URI.parse(urls.first)
|
19
|
-
namespace = parsed_url.path.split('/')[2] ||
|
21
|
+
namespace = parsed_url.path.split('/')[2] || DEFAULT_NAMESPACE
|
20
22
|
Redis::Namespace.new(namespace, redis: Redis::Distributed.new(urls))
|
21
23
|
end
|
22
24
|
end
|
@@ -25,18 +27,42 @@ module Routemaster
|
|
25
27
|
_cleanup
|
26
28
|
end
|
27
29
|
|
30
|
+
# Allow to inject pre-built Redis clients
|
31
|
+
#
|
32
|
+
# Before storing a new connection, ensures that any previously
|
33
|
+
# set client is properly closed.
|
34
|
+
#
|
35
|
+
def inject(clients={})
|
36
|
+
@_injected_clients = true
|
37
|
+
clients.each_pair do |name, client|
|
38
|
+
_close_if_present(@_connections[name])
|
39
|
+
@_connections[name] = Redis::Namespace.new(DEFAULT_NAMESPACE, redis: client)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
28
43
|
private
|
29
44
|
|
45
|
+
# Do not clean up if the clients are injected by the host application.
|
46
|
+
# In that case connections should be managed the server or worker processes.
|
47
|
+
#
|
30
48
|
def _check_for_fork
|
31
|
-
|
49
|
+
return if @_injected_clients
|
50
|
+
return if Process.pid == @_pid
|
51
|
+
_cleanup
|
32
52
|
end
|
33
53
|
|
34
54
|
def _cleanup
|
35
55
|
@_pid = Process.pid
|
36
|
-
@_connections.each_value
|
56
|
+
@_connections.each_value { |conn| _close_if_present(conn) }
|
37
57
|
@_connections = {}
|
38
58
|
end
|
39
59
|
|
60
|
+
def _close_if_present(connection)
|
61
|
+
if connection.respond_to?(:redis)
|
62
|
+
connection.redis.quit
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
40
66
|
end
|
41
67
|
end
|
42
68
|
|
@@ -4,10 +4,9 @@ require_relative '../../lib/routemaster/redis_broker'
|
|
4
4
|
|
5
5
|
describe Routemaster::RedisBroker do
|
6
6
|
subject { Class.new(Routemaster::RedisBroker).instance }
|
7
|
+
let(:urls) { ['redis://localhost/12'] }
|
7
8
|
|
8
9
|
describe "#get" do
|
9
|
-
let(:urls) { ['redis://localhost/12'] }
|
10
|
-
|
11
10
|
context "setting up a redis namespace" do
|
12
11
|
let(:redis) { instance_double(Redis, id: 1) }
|
13
12
|
let(:redis_namespace) { instance_double(Redis::Namespace) }
|
@@ -53,4 +52,29 @@ describe Routemaster::RedisBroker do
|
|
53
52
|
end
|
54
53
|
end
|
55
54
|
end
|
55
|
+
|
56
|
+
describe "#inject_clients" do
|
57
|
+
let(:drain_client) { instance_double(Redis) }
|
58
|
+
let(:cache_client) { instance_double(Redis) }
|
59
|
+
|
60
|
+
before do
|
61
|
+
# Reset the singleton
|
62
|
+
Routemaster::RedisBroker.instance_exec { @singleton__instance__ = nil }
|
63
|
+
|
64
|
+
subject.inject(drain_client: drain_client, cache_client: cache_client)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "sets stores the provided clients for later use" do
|
68
|
+
drain = subject.get(:drain_client, urls: urls)
|
69
|
+
expect(drain).to be_a(Redis::Namespace)
|
70
|
+
expect(drain.namespace).to eql 'rm'
|
71
|
+
expect(drain.redis).to eql drain_client
|
72
|
+
|
73
|
+
|
74
|
+
cache = subject.get(:cache_client, urls: urls)
|
75
|
+
expect(cache).to be_a(Redis::Namespace)
|
76
|
+
expect(cache.namespace).to eql 'rm'
|
77
|
+
expect(cache.redis).to eql cache_client
|
78
|
+
end
|
79
|
+
end
|
56
80
|
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: 2.5.
|
4
|
+
version: 2.5.3
|
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-06-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|