sneakers 2.2.1 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -2
- data/examples/benchmark_worker.rb +2 -1
- data/examples/max_retry_handler.rb +2 -3
- data/examples/workflow_worker.rb +2 -3
- data/lib/sneakers.rb +0 -1
- data/lib/sneakers/configuration.rb +34 -5
- data/lib/sneakers/publisher.rb +9 -2
- data/lib/sneakers/queue.rb +2 -6
- data/lib/sneakers/version.rb +1 -1
- data/spec/sneakers/publisher_spec.rb +46 -4
- data/spec/sneakers/queue_spec.rb +9 -5
- data/spec/sneakers/worker_spec.rb +86 -12
- 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: 3e5b3a5d3740de3c7404234fad5dfe7286d8684a
|
4
|
+
data.tar.gz: fce6b1c8aedb2f0755a16be3d493205badb985a2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b4f462c76d5c6a36bf1d8b2731b1329461f529c12a77604ad9e2cb5f526832ffcfc94aed16239bade4b18f89626c40fd5469e4d2295b97d38bc6df130e87c828
|
7
|
+
data.tar.gz: 7fd337c1fd808b6c1ec19e186b0a70879ee10f8fbb7a81ae5527a9ba5df4434468ce8a90a3532a7de0f0a6970b105a9b79aa128ccc3d9c2b04d0fa8fe376db20
|
data/.travis.yml
CHANGED
@@ -9,9 +9,8 @@ Sneakers.configure(:handler => Sneakers::Handlers::Maxretry,
|
|
9
9
|
:threads => 1,
|
10
10
|
:prefetch => 1,
|
11
11
|
:exchange => 'sneakers',
|
12
|
-
:
|
13
|
-
:routing_key => ['#', 'something']
|
14
|
-
:durable => true,
|
12
|
+
:exchange_options => { :type => 'topic', durable: true },
|
13
|
+
:routing_key => ['#', 'something']
|
15
14
|
)
|
16
15
|
Sneakers.logger.level = Logger::DEBUG
|
17
16
|
|
data/examples/workflow_worker.rb
CHANGED
@@ -4,7 +4,8 @@ require 'sneakers'
|
|
4
4
|
class WorkflowWorker
|
5
5
|
include Sneakers::Worker
|
6
6
|
from_queue 'downloads',
|
7
|
-
:durable
|
7
|
+
exchange_options: { durable: false },
|
8
|
+
queue_options: { durable: false },
|
8
9
|
:ack => true,
|
9
10
|
:threads => 50,
|
10
11
|
:prefetch => 50,
|
@@ -20,5 +21,3 @@ class WorkflowWorker
|
|
20
21
|
ack!
|
21
22
|
end
|
22
23
|
end
|
23
|
-
|
24
|
-
|
data/lib/sneakers.rb
CHANGED
@@ -6,6 +6,20 @@ module Sneakers
|
|
6
6
|
extend Forwardable
|
7
7
|
def_delegators :@hash, :to_hash, :[], :[]=, :==, :fetch, :delete, :has_key?
|
8
8
|
|
9
|
+
EXCHANGE_OPTION_DEFAULTS = {
|
10
|
+
:type => :direct,
|
11
|
+
:durable => true,
|
12
|
+
:auto_delete => false,
|
13
|
+
:arguments => {} # Passed as :arguments to Bunny::Channel#exchange
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
QUEUE_OPTION_DEFAULTS = {
|
17
|
+
:durable => true,
|
18
|
+
:auto_delete => false,
|
19
|
+
:exclusive => false,
|
20
|
+
:arguments => {}
|
21
|
+
}.freeze
|
22
|
+
|
9
23
|
DEFAULTS = {
|
10
24
|
# runner
|
11
25
|
:runner_config_file => nil,
|
@@ -22,13 +36,12 @@ module Sneakers
|
|
22
36
|
:prefetch => 10,
|
23
37
|
:threads => 10,
|
24
38
|
:share_threads => false,
|
25
|
-
:durable => true,
|
26
39
|
:ack => true,
|
27
40
|
:heartbeat => 2,
|
41
|
+
:hooks => {},
|
28
42
|
:exchange => 'sneakers',
|
29
|
-
:
|
30
|
-
:
|
31
|
-
:hooks => {}
|
43
|
+
:exchange_options => EXCHANGE_OPTION_DEFAULTS,
|
44
|
+
:queue_options => QUEUE_OPTION_DEFAULTS
|
32
45
|
}.freeze
|
33
46
|
|
34
47
|
|
@@ -44,6 +57,9 @@ module Sneakers
|
|
44
57
|
|
45
58
|
def merge!(hash)
|
46
59
|
hash = hash.dup
|
60
|
+
hash = map_deprecated_exchange_options_key(hash, :exchange_type, :type)
|
61
|
+
hash = map_deprecated_exchange_options_key(hash, :exchange_arguments, :arguments)
|
62
|
+
hash = map_deprecated_exchange_options_key(hash, :durable, :durable)
|
47
63
|
|
48
64
|
# parse vhost from amqp if vhost is not specified explicitly, only
|
49
65
|
# if we're not given a connection to use.
|
@@ -62,7 +78,7 @@ module Sneakers
|
|
62
78
|
end
|
63
79
|
end
|
64
80
|
|
65
|
-
@hash
|
81
|
+
@hash = deep_merge(@hash, hash)
|
66
82
|
end
|
67
83
|
|
68
84
|
def merge(hash)
|
@@ -82,5 +98,18 @@ module Sneakers
|
|
82
98
|
end
|
83
99
|
alias_method :inspect_without_redaction, :inspect
|
84
100
|
alias_method :inspect, :inspect_with_redaction
|
101
|
+
|
102
|
+
def map_deprecated_exchange_options_key(hash = {}, deprecated_key, key)
|
103
|
+
return hash if hash[deprecated_key].nil?
|
104
|
+
hash = deep_merge({ exchange_options: { key => hash[deprecated_key] } }, hash)
|
105
|
+
hash = deep_merge({ queue_options: { key => hash[deprecated_key] } }, hash) if deprecated_key == :durable
|
106
|
+
hash.delete(deprecated_key)
|
107
|
+
hash
|
108
|
+
end
|
109
|
+
|
110
|
+
def deep_merge(first, second)
|
111
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : v2 }
|
112
|
+
first.merge(second, &merger)
|
113
|
+
end
|
85
114
|
end
|
86
115
|
end
|
data/lib/sneakers/publisher.rb
CHANGED
@@ -20,15 +20,22 @@ module Sneakers
|
|
20
20
|
|
21
21
|
private
|
22
22
|
def ensure_connection!
|
23
|
-
|
23
|
+
# If we've already got a bunny object, use it. This allows people to
|
24
|
+
# specify all kinds of options we don't need to know about (e.g. for ssl).
|
25
|
+
@bunny = @opts[:connection]
|
26
|
+
@bunny ||= create_bunny_connection
|
24
27
|
@bunny.start
|
25
28
|
@channel = @bunny.create_channel
|
26
|
-
@exchange = @channel.exchange(@opts[:exchange],
|
29
|
+
@exchange = @channel.exchange(@opts[:exchange], @opts[:exchange_options])
|
27
30
|
end
|
28
31
|
|
29
32
|
def connected?
|
30
33
|
@bunny && @bunny.connected?
|
31
34
|
end
|
35
|
+
|
36
|
+
def create_bunny_connection
|
37
|
+
Bunny.new(@opts[:amqp], :vhost => @opts[:vhost], :heartbeat => @opts[:heartbeat], :logger => Sneakers::logger)
|
38
|
+
end
|
32
39
|
end
|
33
40
|
end
|
34
41
|
|
data/lib/sneakers/queue.rb
CHANGED
@@ -26,10 +26,7 @@ class Sneakers::Queue
|
|
26
26
|
@channel.prefetch(@opts[:prefetch])
|
27
27
|
|
28
28
|
exchange_name = @opts[:exchange]
|
29
|
-
@exchange = @channel.exchange(exchange_name,
|
30
|
-
:type => @opts[:exchange_type],
|
31
|
-
:durable => @opts[:durable],
|
32
|
-
:arguments => @opts[:exchange_arguments])
|
29
|
+
@exchange = @channel.exchange(exchange_name, @opts[:exchange_options])
|
33
30
|
|
34
31
|
routing_key = @opts[:routing_key] || @name
|
35
32
|
routing_keys = [*routing_key]
|
@@ -37,8 +34,7 @@ class Sneakers::Queue
|
|
37
34
|
# TODO: get the arguments from the handler? Retry handler wants this so you
|
38
35
|
# don't have to line up the queue's dead letter argument with the exchange
|
39
36
|
# you'll create for retry.
|
40
|
-
|
41
|
-
queue = @channel.queue(@name, :durable => queue_durable, :arguments => @opts[:arguments])
|
37
|
+
queue = @channel.queue(@name, @opts[:queue_options])
|
42
38
|
|
43
39
|
if exchange_name.length > 0
|
44
40
|
routing_keys.each do |key|
|
data/lib/sneakers/version.rb
CHANGED
@@ -2,6 +2,19 @@ require 'spec_helper'
|
|
2
2
|
require 'sneakers'
|
3
3
|
|
4
4
|
describe Sneakers::Publisher do
|
5
|
+
let :pub_vars do
|
6
|
+
{
|
7
|
+
:prefetch => 25,
|
8
|
+
:durable => true,
|
9
|
+
:ack => true,
|
10
|
+
:heartbeat => 2,
|
11
|
+
:vhost => '/',
|
12
|
+
:exchange => "sneakers",
|
13
|
+
:exchange_type => :direct,
|
14
|
+
:exchange_arguments => { 'x-arg' => 'value' }
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
5
18
|
describe '#publish' do
|
6
19
|
before do
|
7
20
|
Sneakers.clear!
|
@@ -58,14 +71,14 @@ describe Sneakers::Publisher do
|
|
58
71
|
logger = Logger.new('/dev/null')
|
59
72
|
Sneakers.configure(
|
60
73
|
amqp: 'amqp://someuser:somepassword@somehost:5672',
|
61
|
-
heartbeat: 1,
|
62
|
-
|
63
|
-
|
74
|
+
heartbeat: 1,
|
75
|
+
exchange: 'another_exchange',
|
76
|
+
exchange_options: { :type => :topic, :arguments => { 'x-arg' => 'value' } },
|
64
77
|
log: logger,
|
65
78
|
durable: false)
|
66
79
|
|
67
80
|
channel = Object.new
|
68
|
-
mock(channel).exchange('another_exchange', type: :topic, durable: false, arguments: { 'x-arg' => 'value' }) do
|
81
|
+
mock(channel).exchange('another_exchange', type: :topic, durable: false, :auto_delete => false, arguments: { 'x-arg' => 'value' }) do
|
69
82
|
mock(Object.new).publish('test msg', routing_key: 'downloads')
|
70
83
|
end
|
71
84
|
|
@@ -78,7 +91,36 @@ describe Sneakers::Publisher do
|
|
78
91
|
p = Sneakers::Publisher.new
|
79
92
|
|
80
93
|
p.publish('test msg', to_queue: 'downloads')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'should use an externally instantiated bunny session if provided' do
|
97
|
+
logger = Logger.new('/dev/null')
|
98
|
+
channel = Object.new
|
99
|
+
exchange = Object.new
|
100
|
+
existing_session = Bunny.new
|
101
|
+
my_vars = pub_vars.merge(to_queue: 'downloads')
|
102
|
+
|
103
|
+
mock(existing_session).start
|
104
|
+
mock(existing_session).create_channel { channel }
|
81
105
|
|
106
|
+
mock(channel).exchange('another_exchange', type: :topic, durable: false, :auto_delete => false, arguments: { 'x-arg' => 'value' }) do
|
107
|
+
exchange
|
108
|
+
end
|
109
|
+
|
110
|
+
mock(exchange).publish('test msg', my_vars)
|
111
|
+
|
112
|
+
Sneakers.configure(
|
113
|
+
connection: existing_session,
|
114
|
+
heartbeat: 1, exchange: 'another_exchange',
|
115
|
+
exchange_type: :topic,
|
116
|
+
exchange_arguments: { 'x-arg' => 'value' },
|
117
|
+
log: logger,
|
118
|
+
durable: false
|
119
|
+
)
|
120
|
+
|
121
|
+
p = Sneakers::Publisher.new
|
122
|
+
p.publish('test msg', my_vars)
|
123
|
+
p.instance_variable_get(:@bunny).must_equal existing_session
|
82
124
|
end
|
83
125
|
end
|
84
126
|
end
|
data/spec/sneakers/queue_spec.rb
CHANGED
@@ -5,13 +5,18 @@ describe Sneakers::Queue do
|
|
5
5
|
let :queue_vars do
|
6
6
|
{
|
7
7
|
:prefetch => 25,
|
8
|
-
:durable => true,
|
9
8
|
:ack => true,
|
10
9
|
:heartbeat => 2,
|
11
10
|
:vhost => '/',
|
12
11
|
:exchange => "sneakers",
|
13
|
-
:
|
14
|
-
|
12
|
+
:exchange_options => {
|
13
|
+
:type => :direct,
|
14
|
+
durable: true,
|
15
|
+
:arguments => { 'x-arg' => 'value' }
|
16
|
+
},
|
17
|
+
queue_options: {
|
18
|
+
durable: true
|
19
|
+
}
|
15
20
|
}
|
16
21
|
end
|
17
22
|
|
@@ -81,7 +86,7 @@ describe Sneakers::Queue do
|
|
81
86
|
|
82
87
|
it "creates a non-durable queue if :queue_durable => false" do
|
83
88
|
mock(@mkchan).queue("test_nondurable", :durable => false) { @mkqueue_nondurable }
|
84
|
-
queue_vars[:
|
89
|
+
queue_vars[:queue_options][:durable] = false
|
85
90
|
q = Sneakers::Queue.new("test_nondurable", queue_vars)
|
86
91
|
|
87
92
|
mock(@mkqueue_nondurable).bind(@mkex, :routing_key => "test_nondurable")
|
@@ -144,4 +149,3 @@ describe Sneakers::Queue do
|
|
144
149
|
end
|
145
150
|
end
|
146
151
|
end
|
147
|
-
|
@@ -6,7 +6,18 @@ require 'timeout'
|
|
6
6
|
class DummyWorker
|
7
7
|
include Sneakers::Worker
|
8
8
|
from_queue 'downloads',
|
9
|
-
:
|
9
|
+
:exchange_options => {
|
10
|
+
:type => :topic,
|
11
|
+
:durable => false,
|
12
|
+
:auto_delete => true,
|
13
|
+
:arguments => { 'x-arg' => 'value' }
|
14
|
+
},
|
15
|
+
:queue_options => {
|
16
|
+
:durable => false,
|
17
|
+
:auto_delete => true,
|
18
|
+
:exclusive => true,
|
19
|
+
:arguments => { 'x-arg' => 'value' }
|
20
|
+
},
|
10
21
|
:ack => false,
|
11
22
|
:threads => 50,
|
12
23
|
:prefetch => 40,
|
@@ -101,6 +112,16 @@ class WithParamsWorker
|
|
101
112
|
end
|
102
113
|
end
|
103
114
|
|
115
|
+
class WithDeprecatedExchangeOptionsWorker
|
116
|
+
include Sneakers::Worker
|
117
|
+
from_queue 'defaults',
|
118
|
+
:durable => false,
|
119
|
+
:exchange_type => :topic,
|
120
|
+
:exchange_arguments => { 'x-arg' => 'value' }
|
121
|
+
|
122
|
+
def work(msg)
|
123
|
+
end
|
124
|
+
end
|
104
125
|
|
105
126
|
class TestPool
|
106
127
|
def process(*args,&block)
|
@@ -153,12 +174,8 @@ describe Sneakers::Worker do
|
|
153
174
|
|
154
175
|
describe "#initialize" do
|
155
176
|
describe "builds an internal queue" do
|
156
|
-
before do
|
157
|
-
@dummy_q = DummyWorker.new.queue
|
158
|
-
@defaults_q = DefaultsWorker.new.queue
|
159
|
-
end
|
160
|
-
|
161
177
|
it "should build a queue with correct configuration given defaults" do
|
178
|
+
@defaults_q = DefaultsWorker.new.queue
|
162
179
|
@defaults_q.name.must_equal('defaults')
|
163
180
|
@defaults_q.opts.to_hash.must_equal(
|
164
181
|
:runner_config_file => nil,
|
@@ -172,13 +189,22 @@ describe Sneakers::Worker do
|
|
172
189
|
:prefetch => 10,
|
173
190
|
:threads => 10,
|
174
191
|
:share_threads => false,
|
175
|
-
:durable => true,
|
176
192
|
:ack => true,
|
177
193
|
:amqp => "amqp://guest:guest@localhost:5672",
|
178
194
|
:vhost => "/",
|
179
195
|
:exchange => "sneakers",
|
180
|
-
:
|
181
|
-
|
196
|
+
:exchange_options => {
|
197
|
+
:type => :direct,
|
198
|
+
:durable => true,
|
199
|
+
:auto_delete => false,
|
200
|
+
:arguments => {}
|
201
|
+
},
|
202
|
+
:queue_options => {
|
203
|
+
:durable => true,
|
204
|
+
:auto_delete => false,
|
205
|
+
:exclusive => false,
|
206
|
+
:arguments => {}
|
207
|
+
},
|
182
208
|
:hooks => {},
|
183
209
|
:handler => Sneakers::Handlers::Oneshot,
|
184
210
|
:heartbeat => 2,
|
@@ -187,6 +213,7 @@ describe Sneakers::Worker do
|
|
187
213
|
end
|
188
214
|
|
189
215
|
it "should build a queue with given configuration" do
|
216
|
+
@dummy_q = DummyWorker.new.queue
|
190
217
|
@dummy_q.name.must_equal('downloads')
|
191
218
|
@dummy_q.opts.to_hash.must_equal(
|
192
219
|
:runner_config_file => nil,
|
@@ -200,19 +227,66 @@ describe Sneakers::Worker do
|
|
200
227
|
:prefetch => 40,
|
201
228
|
:threads => 50,
|
202
229
|
:share_threads => false,
|
203
|
-
:durable => false,
|
204
230
|
:ack => false,
|
205
231
|
:amqp => "amqp://guest:guest@localhost:5672",
|
206
232
|
:vhost => "/",
|
207
233
|
:exchange => "dummy",
|
208
|
-
:
|
209
|
-
|
234
|
+
:exchange_options => {
|
235
|
+
:type => :topic,
|
236
|
+
:durable => false,
|
237
|
+
:auto_delete => true,
|
238
|
+
:arguments => { 'x-arg' => 'value' }
|
239
|
+
},
|
240
|
+
:queue_options => {
|
241
|
+
:durable => false,
|
242
|
+
:auto_delete => true,
|
243
|
+
:exclusive => true,
|
244
|
+
:arguments => { 'x-arg' => 'value' }
|
245
|
+
},
|
210
246
|
:hooks => {},
|
211
247
|
:handler => Sneakers::Handlers::Oneshot,
|
212
248
|
:heartbeat => 5,
|
213
249
|
:amqp_heartbeat => 10
|
214
250
|
)
|
215
251
|
end
|
252
|
+
|
253
|
+
it "should build a queue with correct configuration given deprecated exchange options" do
|
254
|
+
@deprecated_exchange_opts_q = WithDeprecatedExchangeOptionsWorker.new.queue
|
255
|
+
@deprecated_exchange_opts_q.name.must_equal('defaults')
|
256
|
+
@deprecated_exchange_opts_q.opts.to_hash.must_equal(
|
257
|
+
:runner_config_file => nil,
|
258
|
+
:metrics => nil,
|
259
|
+
:daemonize => true,
|
260
|
+
:start_worker_delay => 0.2,
|
261
|
+
:workers => 4,
|
262
|
+
:log => "sneakers.log",
|
263
|
+
:pid_path => "sneakers.pid",
|
264
|
+
:timeout_job_after => 5,
|
265
|
+
:prefetch => 10,
|
266
|
+
:threads => 10,
|
267
|
+
:share_threads => false,
|
268
|
+
:ack => true,
|
269
|
+
:amqp => "amqp://guest:guest@localhost:5672",
|
270
|
+
:vhost => "/",
|
271
|
+
:exchange => "sneakers",
|
272
|
+
:exchange_options => {
|
273
|
+
:type => :topic,
|
274
|
+
:durable => false,
|
275
|
+
:auto_delete => false,
|
276
|
+
:arguments => { 'x-arg' => 'value' }
|
277
|
+
},
|
278
|
+
:queue_options => {
|
279
|
+
:durable => false,
|
280
|
+
:auto_delete => false,
|
281
|
+
:exclusive => false,
|
282
|
+
:arguments => {}
|
283
|
+
},
|
284
|
+
:hooks => {},
|
285
|
+
:handler => Sneakers::Handlers::Oneshot,
|
286
|
+
:heartbeat => 2,
|
287
|
+
:amqp_heartbeat => 10
|
288
|
+
)
|
289
|
+
end
|
216
290
|
end
|
217
291
|
|
218
292
|
describe "initializes worker" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sneakers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dotan Nahum
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-10-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: serverengine
|