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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 562f562a5bb003fdf3d00ae2a37eaf8e3201f80c
4
- data.tar.gz: 922e09184bfd33fd91aac65f3ca109a98f85ad46
3
+ metadata.gz: 3e5b3a5d3740de3c7404234fad5dfe7286d8684a
4
+ data.tar.gz: fce6b1c8aedb2f0755a16be3d493205badb985a2
5
5
  SHA512:
6
- metadata.gz: 5261d1b94c18d35bd051313865eec1612a74cfa1b4b5d340f942eec951f3f8fc0cf1f5f169c47ac48a57ef9bbd5aee62baffcdef8eb18741542fe64ce1beaa14
7
- data.tar.gz: fbcb6831ef3fa9f5fd28a6ac12c1ef8a83e12aed46e0834a128fc43e752c6bc7f435dfc51fa5cd3307b168ca7b130bc6be0dd702738ceda8e00390d8488e9cf7
6
+ metadata.gz: b4f462c76d5c6a36bf1d8b2731b1329461f529c12a77604ad9e2cb5f526832ffcfc94aed16239bade4b18f89626c40fd5469e4d2295b97d38bc6df130e87c828
7
+ data.tar.gz: 7fd337c1fd808b6c1ec19e186b0a70879ee10f8fbb7a81ae5527a9ba5df4434468ce8a90a3532a7de0f0a6970b105a9b79aa128ccc3d9c2b04d0fa8fe376db20
@@ -1,11 +1,15 @@
1
- env:
2
- - INTEGRATION_LOG=1 INTEGRATION=1
3
1
  services:
4
2
  - rabbitmq
5
3
  - redis-server
6
4
  language: ruby
7
5
  rvm:
6
+ - ruby-head
8
7
  - 2.2
9
8
  - 2.1
10
9
  - 2.0.0
10
+ matrix:
11
+ include:
12
+ - rvm: 2.2
13
+ env: INTEGRATION_LOG=1 INTEGRATION=1
14
+
11
15
 
@@ -4,7 +4,8 @@ require 'sneakers'
4
4
  class BenchmarkWorker
5
5
  include Sneakers::Worker
6
6
  from_queue 'downloads',
7
- :durable => false,
7
+ exchange_options: { durable: false },
8
+ queue_options: { durable: false },
8
9
  :ack => true,
9
10
  :threads => 50,
10
11
  :prefetch => 50,
@@ -9,9 +9,8 @@ Sneakers.configure(:handler => Sneakers::Handlers::Maxretry,
9
9
  :threads => 1,
10
10
  :prefetch => 1,
11
11
  :exchange => 'sneakers',
12
- :exchange_type => 'topic',
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
 
@@ -4,7 +4,8 @@ require 'sneakers'
4
4
  class WorkflowWorker
5
5
  include Sneakers::Worker
6
6
  from_queue 'downloads',
7
- :durable => false,
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
-
@@ -27,7 +27,6 @@ module Sneakers
27
27
  def configure(opts={})
28
28
  # worker > userland > defaults
29
29
  CONFIG.merge!(opts)
30
-
31
30
  setup_general_logger!
32
31
  setup_worker_concerns!
33
32
  setup_general_publisher!
@@ -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
- :exchange_type => :direct,
30
- :exchange_arguments => {}, # Passed as :arguments to Bunny::Channel#exchange
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.merge!(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
@@ -20,15 +20,22 @@ module Sneakers
20
20
 
21
21
  private
22
22
  def ensure_connection!
23
- @bunny = Bunny.new(@opts[:amqp], heartbeat: @opts[:heartbeat], vhost: @opts[:vhost], :logger => Sneakers::logger)
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], type: @opts[:exchange_type], durable: @opts[:durable], arguments: @opts[:exchange_arguments])
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
 
@@ -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
- queue_durable = @opts[:queue_durable].nil? ? @opts[:durable] : @opts[:queue_durable]
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|
@@ -1,3 +1,3 @@
1
1
  module Sneakers
2
- VERSION = "2.2.1"
2
+ VERSION = "2.3.0"
3
3
  end
@@ -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, exchange: 'another_exchange',
62
- exchange_type: :topic,
63
- exchange_arguments: { 'x-arg' => 'value' },
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
@@ -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
- :exchange_type => :direct,
14
- :exchange_arguments => { 'x-arg' => 'value' }
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[:queue_durable] = false
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
- :durable => false,
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
- :exchange_type => :direct,
181
- :exchange_arguments => {},
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
- :exchange_type => :direct,
209
- :exchange_arguments => {},
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.2.1
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-09-29 00:00:00.000000000 Z
11
+ date: 2015-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: serverengine