shoryuken 3.0.4 → 3.1.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.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +79 -0
  5. data/Gemfile +1 -0
  6. data/README.md +15 -117
  7. data/bin/cli/base.rb +0 -2
  8. data/bin/cli/sqs.rb +18 -1
  9. data/bin/shoryuken +9 -1
  10. data/examples/default_worker.rb +1 -1
  11. data/lib/shoryuken/default_worker_registry.rb +2 -2
  12. data/lib/shoryuken/environment_loader.rb +33 -13
  13. data/lib/shoryuken/fetcher.rb +17 -16
  14. data/lib/shoryuken/launcher.rb +86 -7
  15. data/lib/shoryuken/manager.rb +42 -72
  16. data/lib/shoryuken/middleware/server/auto_delete.rb +3 -8
  17. data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +4 -4
  18. data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +8 -2
  19. data/lib/shoryuken/middleware/server/timing.rb +2 -2
  20. data/lib/shoryuken/options.rb +192 -0
  21. data/lib/shoryuken/polling/base.rb +67 -0
  22. data/lib/shoryuken/polling/strict_priority.rb +77 -0
  23. data/lib/shoryuken/polling/weighted_round_robin.rb +66 -0
  24. data/lib/shoryuken/processor.rb +23 -17
  25. data/lib/shoryuken/queue.rb +27 -6
  26. data/lib/shoryuken/runner.rb +3 -15
  27. data/lib/shoryuken/version.rb +1 -1
  28. data/lib/shoryuken/worker.rb +8 -0
  29. data/lib/shoryuken.rb +39 -172
  30. data/shoryuken.gemspec +1 -1
  31. data/spec/integration/launcher_spec.rb +12 -6
  32. data/spec/shoryuken/environment_loader_spec.rb +3 -12
  33. data/spec/shoryuken/fetcher_spec.rb +30 -15
  34. data/spec/shoryuken/manager_spec.rb +12 -13
  35. data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +1 -1
  36. data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +1 -1
  37. data/spec/shoryuken/options_spec.rb +100 -0
  38. data/spec/shoryuken/{polling_spec.rb → polling/strict_priority_spec.rb} +1 -100
  39. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +99 -0
  40. data/spec/shoryuken/processor_spec.rb +20 -37
  41. data/spec/shoryuken/queue_spec.rb +72 -26
  42. data/spec/shoryuken/runner_spec.rb +3 -4
  43. data/spec/shoryuken_spec.rb +0 -59
  44. data/spec/spec_helper.rb +8 -2
  45. data/test_workers/endless_uninterruptive_worker.rb +1 -1
  46. metadata +14 -7
  47. data/lib/shoryuken/polling.rb +0 -204
@@ -2,32 +2,41 @@ module Shoryuken
2
2
  class Processor
3
3
  include Util
4
4
 
5
- def initialize(manager)
6
- @manager = manager
5
+ attr_reader :queue, :sqs_msg
6
+
7
+ def initialize(queue, sqs_msg)
8
+ @queue = queue
9
+ @sqs_msg = sqs_msg
7
10
  end
8
11
 
9
- def process(queue, sqs_msg)
10
- worker = Shoryuken.worker_registry.fetch_worker(queue, sqs_msg)
11
- body = get_body(worker.class, sqs_msg)
12
+ def process
13
+ return logger.error { "No worker found for #{queue}" } unless worker
12
14
 
13
15
  worker.class.server_middleware.invoke(worker, queue, sqs_msg, body) do
14
16
  worker.perform(sqs_msg, body)
15
17
  end
16
- ensure
17
- @manager.processor_done(queue)
18
+ rescue Exception => ex
19
+ logger.error { "Processor failed: #{ex.message}" }
20
+ logger.error { ex.backtrace.join("\n") } unless ex.backtrace.nil?
21
+
22
+ raise
18
23
  end
19
24
 
20
25
  private
21
26
 
22
- def get_body(worker_class, sqs_msg)
23
- if sqs_msg.is_a? Array
24
- sqs_msg.map { |m| parse_body(worker_class, m) }
25
- else
26
- parse_body(worker_class, sqs_msg)
27
- end
27
+ def worker
28
+ @_worker ||= Shoryuken.worker_registry.fetch_worker(queue, sqs_msg)
28
29
  end
29
30
 
30
- def parse_body(worker_class, sqs_msg)
31
+ def worker_class
32
+ worker.class
33
+ end
34
+
35
+ def body
36
+ @_body ||= sqs_msg.is_a?(Array) ? sqs_msg.map(&method(:parse_body)) : parse_body(sqs_msg)
37
+ end
38
+
39
+ def parse_body(sqs_msg)
31
40
  body_parser = worker_class.get_shoryuken_options['body_parser']
32
41
 
33
42
  case body_parser
@@ -47,9 +56,6 @@ module Shoryuken
47
56
  body_parser.load(sqs_msg.body)
48
57
  end
49
58
  end
50
- rescue => e
51
- logger.error { "Error parsing the message body: #{e.message}\nbody_parser: #{body_parser}\nsqs_msg.body: #{sqs_msg.body}" }
52
- raise
53
59
  end
54
60
  end
55
61
  end
@@ -1,17 +1,16 @@
1
1
  module Shoryuken
2
2
  class Queue
3
+ include Util
4
+
3
5
  FIFO_ATTR = 'FifoQueue'
4
6
  MESSAGE_GROUP_ID = 'ShoryukenMessage'
5
7
  VISIBILITY_TIMEOUT_ATTR = 'VisibilityTimeout'
6
8
 
7
9
  attr_accessor :name, :client, :url
8
10
 
9
- def initialize(client, name)
10
- self.name = name
11
+ def initialize(client, name_or_url)
11
12
  self.client = client
12
- self.url = client.get_queue_url(queue_name: name).queue_url
13
- rescue Aws::SQS::Errors::NonExistentQueue => e
14
- raise e, "The specified queue '#{name}' does not exist."
13
+ set_name_and_url(name_or_url)
15
14
  end
16
15
 
17
16
  def visibility_timeout
@@ -19,7 +18,13 @@ module Shoryuken
19
18
  end
20
19
 
21
20
  def delete_messages(options)
22
- client.delete_message_batch(options.merge(queue_url: url))
21
+ client.delete_message_batch(
22
+ options.merge(queue_url: url)
23
+ ).failed.any? do |failure|
24
+ logger.error do
25
+ "Could not delete #{failure.id}, code: '#{failure.code}', message: '#{failure.message}', sender_fault: #{failure.sender_fault}"
26
+ end
27
+ end
23
28
  end
24
29
 
25
30
  def send_message(options)
@@ -44,6 +49,22 @@ module Shoryuken
44
49
 
45
50
  private
46
51
 
52
+ def set_name(name)
53
+ self.name = name
54
+ self.url = client.get_queue_url(queue_name: name).queue_url
55
+ rescue Aws::Errors::NoSuchEndpointError, Aws::SQS::Errors::NonExistentQueue => ex
56
+ raise ex, "The specified queue #{name} does not exist."
57
+ end
58
+
59
+ def set_url(url)
60
+ self.name = url.split('/').last
61
+ self.url = url
62
+ end
63
+
64
+ def set_name_and_url(name_or_url)
65
+ name_or_url.start_with?('https://sqs.') ? set_url(name_or_url) : set_name(name_or_url)
66
+ end
67
+
47
68
  def queue_attributes
48
69
  # Note: Retrieving all queue attributes as requesting `FifoQueue` on non-FIFO queue raises error.
49
70
  # See issue: https://github.com/aws/aws-sdk-ruby/issues/1350
@@ -19,7 +19,7 @@ module Shoryuken
19
19
  def run(options)
20
20
  self_read, self_write = IO.pipe
21
21
 
22
- %w(INT TERM USR1 USR2 TTIN).each do |sig|
22
+ %w(INT TERM USR1 TTIN).each do |sig|
23
23
  begin
24
24
  trap sig do
25
25
  self_write.puts(sig)
@@ -43,22 +43,15 @@ module Shoryuken
43
43
 
44
44
  @launcher = Shoryuken::Launcher.new
45
45
 
46
- if (callback = Shoryuken.start_callback)
47
- logger.info { 'Calling Shoryuken.on_start block' }
48
- callback.call
49
- end
50
-
51
- fire_event(:startup)
52
-
53
46
  begin
54
- @launcher.run
47
+ @launcher.start
55
48
 
56
49
  while (readable_io = IO.select([self_read]))
57
50
  signal = readable_io.first[0].gets.strip
58
51
  handle_signal(signal)
59
52
  end
60
53
  rescue Interrupt
61
- @launcher.stop(shutdown: true)
54
+ @launcher.stop!
62
55
  exit 0
63
56
  end
64
57
  end
@@ -110,7 +103,6 @@ module Shoryuken
110
103
  logger.info { 'Received USR1, will soft shutdown down' }
111
104
 
112
105
  @launcher.stop
113
- fire_event(:quiet, true)
114
106
  exit 0
115
107
  end
116
108
 
@@ -126,13 +118,9 @@ module Shoryuken
126
118
  end
127
119
 
128
120
  def handle_signal(sig)
129
- logger.info { "Got #{sig} signal" }
130
-
131
121
  case sig
132
122
  when 'USR1' then execute_soft_shutdown
133
123
  when 'TTIN' then print_threads_backtrace
134
- when 'USR2'
135
- logger.warn { "Received #{sig}, will do nothing. To execute soft shutdown, please send USR1" }
136
124
  else
137
125
  logger.info { "Received #{sig}, will shutdown down" }
138
126
 
@@ -1,3 +1,3 @@
1
1
  module Shoryuken
2
- VERSION = '3.0.4'.freeze
2
+ VERSION = '3.1.0'.freeze
3
3
  end
@@ -48,6 +48,14 @@ module Shoryuken
48
48
  !!get_shoryuken_options['auto_visibility_timeout']
49
49
  end
50
50
 
51
+ def exponential_backoff?
52
+ !!get_shoryuken_options['retry_intervals']
53
+ end
54
+
55
+ def auto_delete?
56
+ !!(get_shoryuken_options['delete'] || get_shoryuken_options['auto_delete'])
57
+ end
58
+
51
59
  def get_shoryuken_options # :nodoc:
52
60
  @shoryuken_options || Shoryuken.default_worker_options
53
61
  end
data/lib/shoryuken.rb CHANGED
@@ -20,184 +20,51 @@ require 'shoryuken/middleware/server/auto_delete'
20
20
  Shoryuken::Middleware::Server.autoload :AutoExtendVisibility, 'shoryuken/middleware/server/auto_extend_visibility'
21
21
  require 'shoryuken/middleware/server/exponential_backoff_retry'
22
22
  require 'shoryuken/middleware/server/timing'
23
- require 'shoryuken/polling'
23
+ require 'shoryuken/polling/base'
24
+ require 'shoryuken/polling/weighted_round_robin'
25
+ require 'shoryuken/polling/strict_priority'
24
26
  require 'shoryuken/manager'
25
27
  require 'shoryuken/launcher'
26
28
  require 'shoryuken/processor'
27
29
  require 'shoryuken/fetcher'
30
+ require 'shoryuken/options'
28
31
 
29
32
  module Shoryuken
30
- DEFAULTS = {
31
- concurrency: 25,
32
- queues: [],
33
- aws: {},
34
- delay: 0,
35
- timeout: 8,
36
- lifecycle_events: {
37
- startup: [],
38
- quiet: [],
39
- shutdown: []
40
- },
41
- polling_strategy: Polling::WeightedRoundRobin
42
- }.freeze
43
-
44
- @@queues = []
45
- @@worker_registry = DefaultWorkerRegistry.new
46
- @@active_job_queue_name_prefixing = false
47
- @@sqs_client = nil
48
- @@sqs_client_receive_message_opts = {}
49
- @@start_callback = nil
50
- @@stop_callback = nil
51
-
52
- class << self
53
- def queues
54
- @@queues
55
- end
56
-
57
- def add_queue(queue, priority = 1)
58
- priority.times { queues << queue }
59
- end
60
-
61
- def worker_registry
62
- @@worker_registry
63
- end
64
-
65
- def worker_registry=(worker_registry)
66
- @@worker_registry = worker_registry
67
- end
68
-
69
- def start_callback
70
- @@start_callback
71
- end
72
-
73
- def start_callback=(start_callback)
74
- @@start_callback = start_callback
75
- end
76
-
77
- def stop_callback
78
- @@stop_callback
79
- end
80
-
81
- def stop_callback=(stop_callback)
82
- @@stop_callback = stop_callback
83
- end
84
-
85
- def active_job_queue_name_prefixing
86
- @@active_job_queue_name_prefixing
87
- end
88
-
89
- def active_job_queue_name_prefixing=(active_job_queue_name_prefixing)
90
- @@active_job_queue_name_prefixing = active_job_queue_name_prefixing
91
- end
92
-
93
- def sqs_client
94
- @@sqs_client ||= Aws::SQS::Client.new
95
- end
96
-
97
- def sqs_client=(sqs_client)
98
- @@sqs_client = sqs_client
99
- end
100
-
101
- def sqs_client_receive_message_opts
102
- @@sqs_client_receive_message_opts
103
- end
104
-
105
- def sqs_client_receive_message_opts=(sqs_client_receive_message_opts)
106
- @@sqs_client_receive_message_opts = sqs_client_receive_message_opts
107
- end
108
-
109
- def options
110
- @@options ||= DEFAULTS.dup
111
- end
112
-
113
- def logger
114
- Shoryuken::Logging.logger
115
- end
116
-
117
- def register_worker(*args)
118
- @@worker_registry.register_worker(*args)
119
- end
120
-
121
- def configure_server
122
- yield self if server?
123
- end
124
-
125
- def server_middleware
126
- @@server_chain ||= default_server_middleware
127
- yield @@server_chain if block_given?
128
- @@server_chain
129
- end
130
-
131
- def configure_client
132
- yield self unless server?
133
- end
134
-
135
- def client_middleware
136
- @@client_chain ||= default_client_middleware
137
- yield @@client_chain if block_given?
138
- @@client_chain
139
- end
140
-
141
- def default_worker_options
142
- @@default_worker_options ||= {
143
- 'queue' => 'default',
144
- 'delete' => false,
145
- 'auto_delete' => false,
146
- 'auto_visibility_timeout' => false,
147
- 'retry_intervals' => nil,
148
- 'batch' => false
149
- }
150
- end
151
-
152
- def default_worker_options=(default_worker_options)
153
- @@default_worker_options = default_worker_options
154
- end
155
-
156
- def on_start(&block)
157
- @@start_callback = block
158
- end
159
-
160
- def on_stop(&block)
161
- @@stop_callback = block
162
- end
163
-
164
- # Register a block to run at a point in the Shoryuken lifecycle.
165
- # :startup, :quiet or :shutdown are valid events.
166
- #
167
- # Shoryuken.configure_server do |config|
168
- # config.on(:shutdown) do
169
- # puts "Goodbye cruel world!"
170
- # end
171
- # end
172
- def on(event, &block)
173
- fail ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
174
- fail ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
175
- options[:lifecycle_events][event] << block
176
- end
177
-
178
- private
179
-
180
- def default_server_middleware
181
- Middleware::Chain.new do |m|
182
- m.add Middleware::Server::Timing
183
- m.add Middleware::Server::ExponentialBackoffRetry
184
- m.add Middleware::Server::AutoDelete
185
- m.add Middleware::Server::AutoExtendVisibility
186
- if defined?(::ActiveRecord::Base)
187
- require 'shoryuken/middleware/server/active_record'
188
- m.add Middleware::Server::ActiveRecord
189
- end
190
- end
191
- end
192
-
193
- def default_client_middleware
194
- Middleware::Chain.new
195
- end
196
-
197
- def server?
198
- defined?(Shoryuken::CLI)
199
- end
200
- end
33
+ extend SingleForwardable
34
+
35
+ def_delegators(
36
+ :'Shoryuken::Options',
37
+ :add_group,
38
+ :groups,
39
+ :add_queue,
40
+ :ungrouped_queues,
41
+ :worker_registry,
42
+ :worker_registry=,
43
+ :polling_strategy,
44
+ :start_callback,
45
+ :start_callback=,
46
+ :stop_callback,
47
+ :stop_callback=,
48
+ :active_job_queue_name_prefixing,
49
+ :active_job_queue_name_prefixing=,
50
+ :sqs_client,
51
+ :sqs_client=,
52
+ :sqs_client_receive_message_opts,
53
+ :sqs_client_receive_message_opts=,
54
+ :options,
55
+ :logger,
56
+ :register_worker,
57
+ :configure_server,
58
+ :server?,
59
+ :server_middleware,
60
+ :configure_client,
61
+ :client_middleware,
62
+ :default_worker_options,
63
+ :default_worker_options=,
64
+ :on_start,
65
+ :on_stop,
66
+ :on
67
+ )
201
68
  end
202
69
 
203
70
  require 'shoryuken/extensions/active_job_adapter' if defined?(::ActiveJob)
data/shoryuken.gemspec CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
23
23
  spec.add_development_dependency 'pry-byebug'
24
24
  spec.add_development_dependency 'dotenv'
25
25
 
26
- spec.add_dependency 'aws-sdk-core', '~> 2'
26
+ spec.add_dependency 'aws-sdk-core', '> 2'
27
27
  spec.add_dependency 'concurrent-ruby'
28
28
  spec.add_dependency 'thor'
29
29
  end
@@ -6,25 +6,31 @@ require 'securerandom'
6
6
  RSpec.describe Shoryuken::Launcher do
7
7
  describe 'Consuming messages', slow: :true do
8
8
  before do
9
+ Aws.config[:stub_responses] = false
10
+ Aws.config[:region] = 'us-east-1'
11
+
9
12
  StandardWorker.received_messages = 0
10
13
 
11
- queue = "test_shoryuken#{StandardWorker}_#{SecureRandom.uuid}"
14
+ queue = "shoryuken-travis-#{StandardWorker}-#{SecureRandom.uuid}"
12
15
 
13
- Shoryuken::Client.sqs.create_queue queue_name: queue
16
+ Shoryuken::Client.sqs.create_queue(queue_name: queue)
14
17
 
15
- Shoryuken.queues << queue
18
+ Shoryuken.add_group('default', 1)
19
+ Shoryuken.add_queue(queue, 1, 'default')
16
20
 
17
21
  StandardWorker.get_shoryuken_options['queue'] = queue
18
22
 
19
- Shoryuken.register_worker queue, StandardWorker
23
+ Shoryuken.register_worker(queue, StandardWorker)
20
24
  end
21
25
 
22
26
  after do
27
+ Aws.config[:stub_responses] = true
28
+
23
29
  queue_url = Shoryuken::Client.sqs.get_queue_url(
24
30
  queue_name: StandardWorker.get_shoryuken_options['queue']
25
31
  ).queue_url
26
32
 
27
- Shoryuken::Client.sqs.delete_queue queue_url: queue_url
33
+ Shoryuken::Client.sqs.delete_queue(queue_url: queue_url)
28
34
  end
29
35
 
30
36
  it 'consumes as a command worker' do
@@ -61,7 +67,7 @@ RSpec.describe Shoryuken::Launcher do
61
67
  end
62
68
 
63
69
  def poll_queues_until
64
- subject.run
70
+ subject.start
65
71
 
66
72
  Timeout::timeout(10) do
67
73
  begin
@@ -15,20 +15,11 @@ RSpec.describe Shoryuken::EnvironmentLoader do
15
15
  allow(subject).to receive(:patch_deprecated_workers)
16
16
  end
17
17
 
18
- it 'parses' do
19
- Shoryuken.options[:queues] = ['queue_1']
18
+ specify do
19
+ Shoryuken.options[:queues] = ['queue1', ['queue2', 2]]
20
20
  subject.load
21
21
 
22
- expect(Shoryuken.queues).to eq(%w(queue_1))
23
- end
24
-
25
- context 'with priority' do
26
- it 'parses' do
27
- Shoryuken.options[:queues] = ['queue_1', ['queue_2', 2]]
28
- subject.load
29
-
30
- expect(Shoryuken.queues).to eq(%w(queue_1 queue_2 queue_2))
31
- end
22
+ expect(Shoryuken.groups['default'][:queues]).to eq(%w(queue1 queue2 queue2))
32
23
  end
33
24
  end
34
25
  end
@@ -2,36 +2,51 @@ require 'spec_helper'
2
2
  require 'shoryuken/manager'
3
3
  require 'shoryuken/fetcher'
4
4
 
5
- describe Shoryuken::Fetcher do
6
- let(:queue) { instance_double('Shoryuken::Queue') }
7
- let(:queue_name) { 'default' }
5
+ RSpec.describe Shoryuken::Fetcher do
6
+ let(:queue) { instance_double('Shoryuken::Queue') }
7
+ let(:queue_name) { 'default' }
8
8
  let(:queue_config) { Shoryuken::Polling::QueueConfiguration.new(queue_name, {}) }
9
+ let(:group) { 'default' }
9
10
 
10
11
  let(:sqs_msg) do
11
- double(Shoryuken::Message,
12
+ double(
13
+ Shoryuken::Message,
12
14
  queue_url: queue_name,
13
15
  body: 'test',
14
16
  message_id: 'fc754df79cc24c4196ca5996a44b771e',
15
- )
17
+ )
16
18
  end
17
19
 
18
- subject { described_class.new }
20
+ subject { described_class.new(group) }
19
21
 
20
22
  describe '#fetch' do
21
- it 'calls Shoryuken::Client to receive messages' do
23
+ let(:limit) { 1 }
24
+
25
+ specify do
22
26
  expect(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
27
+
28
+ Shoryuken.sqs_client_receive_message_opts[group] = { wait_time_seconds: 10 }
29
+
23
30
  expect(queue).to receive(:receive_messages).
24
- with(max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']).
31
+ with(wait_time_seconds: 10, max_number_of_messages: limit, message_attribute_names: ['All'], attribute_names: ['All']).
25
32
  and_return([])
26
- subject.fetch(queue_config, 1)
33
+
34
+ subject.fetch(queue_config, limit)
27
35
  end
28
36
 
29
- it 'maxes messages to receive to 10 (SQS limit)' do
30
- allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
31
- expect(queue).to receive(:receive_messages).
32
- with(max_number_of_messages: 10, attribute_names: ['All'], message_attribute_names: ['All']).
33
- and_return([])
34
- subject.fetch(queue_config, 20)
37
+ context 'when limit is greater than FETCH_LIMIT' do
38
+ let(:limit) { 20 }
39
+
40
+ specify do
41
+ Shoryuken.sqs_client_receive_message_opts[group] = {}
42
+
43
+ allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
44
+ expect(queue).to receive(:receive_messages).
45
+ with(max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']).
46
+ and_return([])
47
+
48
+ subject.fetch(queue_config, limit)
49
+ end
35
50
  end
36
51
  end
37
52
  end
@@ -11,28 +11,20 @@ RSpec.describe Shoryuken::Manager do
11
11
  let(:queue) { 'default' }
12
12
  let(:queues) { [queue] }
13
13
  let(:polling_strategy) { Shoryuken::Polling::WeightedRoundRobin.new(queues) }
14
- let(:fetcher) { Shoryuken::Fetcher.new }
14
+ let(:fetcher) { double Shoryuken::Fetcher }
15
15
  let(:concurrency) { 1 }
16
16
 
17
- subject { Shoryuken::Manager.new(fetcher, polling_strategy) }
17
+ subject { Shoryuken::Manager.new(fetcher, polling_strategy, concurrency) }
18
18
 
19
- before(:each) do
20
- Shoryuken.options[:concurrency] = concurrency
19
+ before do
20
+ allow(fetcher).to receive(:fetch).and_return([])
21
21
  end
22
22
 
23
- after(:each) do
23
+ after do
24
24
  Shoryuken.options[:concurrency] = 1
25
25
  TestWorker.get_shoryuken_options['batch'] = false
26
26
  end
27
27
 
28
- describe 'Invalid concurrency setting' do
29
- it 'raises ArgumentError if concurrency is not positive number' do
30
- Shoryuken.options[:concurrency] = -1
31
- expect { Shoryuken::Manager.new(nil, nil) }
32
- .to raise_error(ArgumentError, 'Concurrency value -1 is invalid, it needs to be a positive number')
33
- end
34
- end
35
-
36
28
  describe '#start' do
37
29
  xit 'pauses when there are no active queues' do
38
30
  expect(polling_strategy).to receive(:next_queue).and_return(nil)
@@ -55,6 +47,13 @@ RSpec.describe Shoryuken::Manager do
55
47
  end
56
48
  end
57
49
 
50
+ describe '#dispatch' do
51
+ xit 'fires a dispatch event' do
52
+ expect(subject).to receive(:fire_event).with(:dispatch)
53
+ subject.send(:dispatch)
54
+ end
55
+ end
56
+
58
57
  describe '#dispatch_batch' do
59
58
  it 'assings batch as a single message' do
60
59
  q = polling_strategy.next_queue
@@ -34,7 +34,7 @@ RSpec.describe Shoryuken::Middleware::Server::AutoExtendVisibility do
34
34
 
35
35
  context 'when batch worker' do
36
36
  it 'yields' do
37
- expect { |b| subject.call(nil, nil, [], nil, &b) }.to yield_control
37
+ expect { |b| subject.call(TestWorker.new, nil, [], nil, &b) }.to yield_control
38
38
  end
39
39
  end
40
40
 
@@ -13,7 +13,7 @@ RSpec.describe Shoryuken::Middleware::Server::ExponentialBackoffRetry do
13
13
 
14
14
  context 'when batch worker' do
15
15
  it 'yields' do
16
- expect { |b| subject.call(nil, nil, [], nil, &b) }.to yield_control
16
+ expect { |b| subject.call(TestWorker.new, nil, [], nil, &b) }.to yield_control
17
17
  end
18
18
  end
19
19