sneakers 2.2.1 → 2.3.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/.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
|