shoryuken 3.2.3 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +89 -23
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile +4 -0
  5. data/Rakefile +1 -1
  6. data/bin/cli/base.rb +0 -1
  7. data/bin/cli/sqs.rb +3 -3
  8. data/bin/shoryuken +3 -9
  9. data/examples/bootstrap_queues.rb +3 -3
  10. data/examples/default_worker.rb +1 -1
  11. data/lib/shoryuken.rb +0 -1
  12. data/lib/shoryuken/core_ext.rb +1 -1
  13. data/lib/shoryuken/extensions/active_job_adapter.rb +1 -1
  14. data/lib/shoryuken/fetcher.rb +3 -3
  15. data/lib/shoryuken/logging.rb +1 -1
  16. data/lib/shoryuken/middleware/server/active_record.rb +1 -1
  17. data/lib/shoryuken/middleware/server/auto_delete.rb +1 -1
  18. data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +1 -1
  19. data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +1 -1
  20. data/lib/shoryuken/middleware/server/timing.rb +12 -14
  21. data/lib/shoryuken/polling/base.rb +1 -1
  22. data/lib/shoryuken/polling/strict_priority.rb +8 -8
  23. data/lib/shoryuken/queue.rb +3 -3
  24. data/lib/shoryuken/runner.rb +9 -3
  25. data/lib/shoryuken/version.rb +1 -1
  26. data/lib/shoryuken/worker/inline_executor.rb +12 -3
  27. data/lib/shoryuken/worker_registry.rb +4 -4
  28. data/shoryuken.gemspec +5 -5
  29. data/spec/integration/launcher_spec.rb +2 -2
  30. data/spec/shoryuken/body_parser_spec.rb +2 -2
  31. data/spec/shoryuken/client_spec.rb +1 -1
  32. data/spec/shoryuken/core_ext_spec.rb +6 -6
  33. data/spec/shoryuken/default_worker_registry_spec.rb +2 -4
  34. data/spec/shoryuken/environment_loader_spec.rb +4 -4
  35. data/spec/shoryuken/extensions/active_job_adapter_spec.rb +3 -3
  36. data/spec/shoryuken/manager_spec.rb +1 -1
  37. data/spec/shoryuken/middleware/chain_spec.rb +2 -2
  38. data/spec/shoryuken/middleware/server/auto_delete_spec.rb +9 -7
  39. data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +3 -3
  40. data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +5 -3
  41. data/spec/shoryuken/options_spec.rb +5 -5
  42. data/spec/shoryuken/polling/strict_priority_spec.rb +1 -1
  43. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +1 -1
  44. data/spec/shoryuken/processor_spec.rb +1 -1
  45. data/spec/shoryuken/queue_spec.rb +3 -3
  46. data/spec/shoryuken/util_spec.rb +1 -1
  47. data/spec/shoryuken/worker/default_executor_spec.rb +10 -5
  48. data/spec/shoryuken/worker/inline_executor_spec.rb +28 -2
  49. data/spec/shoryuken/worker_spec.rb +7 -9
  50. data/spec/spec_helper.rb +1 -1
  51. data/test_workers/endless_interruptive_worker.rb +2 -2
  52. data/test_workers/endless_uninterruptive_worker.rb +3 -3
  53. metadata +7 -7
@@ -2,9 +2,9 @@ module Shoryuken
2
2
  class Queue
3
3
  include Util
4
4
 
5
- FIFO_ATTR = 'FifoQueue'
6
- MESSAGE_GROUP_ID = 'ShoryukenMessage'
7
- VISIBILITY_TIMEOUT_ATTR = 'VisibilityTimeout'
5
+ FIFO_ATTR = 'FifoQueue'.freeze
6
+ MESSAGE_GROUP_ID = 'ShoryukenMessage'.freeze
7
+ VISIBILITY_TIMEOUT_ATTR = 'VisibilityTimeout'.freeze
8
8
 
9
9
  attr_accessor :name, :client, :url
10
10
 
@@ -8,7 +8,6 @@ require 'shoryuken'
8
8
 
9
9
  module Shoryuken
10
10
  # rubocop:disable Lint/InheritException
11
- # rubocop:disable Metrics/AbcSize
12
11
  # See: https://github.com/mperham/sidekiq/blob/33f5d6b2b6c0dfaab11e5d39688cab7ebadc83ae/lib/sidekiq/cli.rb#L20
13
12
  class Shutdown < Interrupt; end
14
13
 
@@ -19,7 +18,7 @@ module Shoryuken
19
18
  def run(options)
20
19
  self_read, self_write = IO.pipe
21
20
 
22
- %w(INT TERM USR1 TTIN).each do |sig|
21
+ %w[INT TERM USR1 TSTP TTIN].each do |sig|
23
22
  begin
24
23
  trap sig do
25
24
  self_write.puts(sig)
@@ -106,6 +105,12 @@ module Shoryuken
106
105
  exit 0
107
106
  end
108
107
 
108
+ def execute_terminal_stop
109
+ logger.info { 'Received TSTP, will stop accepting new work' }
110
+
111
+ @launcher.stop
112
+ end
113
+
109
114
  def print_threads_backtrace
110
115
  Thread.list.each do |thread|
111
116
  logger.info { "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}" }
@@ -123,8 +128,9 @@ module Shoryuken
123
128
  case sig
124
129
  when 'USR1' then execute_soft_shutdown
125
130
  when 'TTIN' then print_threads_backtrace
131
+ when 'TSTP' then execute_terminal_stop
126
132
  when 'TERM', 'INT'
127
- logger.info { "Received #{sig}, will shutdown down" }
133
+ logger.info { "Received #{sig}, will shutdown" }
128
134
 
129
135
  raise Interrupt
130
136
  end
@@ -1,3 +1,3 @@
1
1
  module Shoryuken
2
- VERSION = '3.2.3'.freeze
2
+ VERSION = '3.3.0'.freeze
3
3
  end
@@ -2,7 +2,7 @@ module Shoryuken
2
2
  module Worker
3
3
  class InlineExecutor
4
4
  class << self
5
- def perform_async(worker_class, body, options = {})
5
+ def perform_async(worker_class, body, _options = {})
6
6
  body = JSON.dump(body) if body.is_a?(Hash)
7
7
 
8
8
  sqs_msg = OpenStruct.new(
@@ -16,11 +16,20 @@ module Shoryuken
16
16
  delete: nil
17
17
  )
18
18
 
19
- worker_class.new.perform(sqs_msg, BodyParser.parse(worker_class, sqs_msg))
19
+ call(worker_class, sqs_msg)
20
20
  end
21
21
 
22
22
  def perform_in(worker_class, _interval, body, options = {})
23
- perform_async(worker_class, body, options)
23
+ worker_class.perform_async(body, options)
24
+ end
25
+
26
+ private
27
+
28
+ def call(worker_class, sqs_msg)
29
+ parsed_body = BodyParser.parse(worker_class, sqs_msg)
30
+ batch = worker_class.shoryuken_options_hash['batch']
31
+ args = batch ? [[sqs_msg], [parsed_body]] : [sqs_msg, parsed_body]
32
+ worker_class.new.perform(*args)
24
33
  end
25
34
  end
26
35
  end
@@ -1,6 +1,6 @@
1
1
  module Shoryuken
2
2
  class WorkerRegistry
3
- def batch_receive_messages?(queue)
3
+ def batch_receive_messages?(_queue)
4
4
  # true if the workers for queue support batch processing of messages
5
5
  fail NotImplementedError
6
6
  end
@@ -10,7 +10,7 @@ module Shoryuken
10
10
  fail NotImplementedError
11
11
  end
12
12
 
13
- def fetch_worker(queue, message)
13
+ def fetch_worker(_queue, _message)
14
14
  # must return an instance of the worker that handles
15
15
  # message received on queue
16
16
  fail NotImplementedError
@@ -21,12 +21,12 @@ module Shoryuken
21
21
  fail NotImplementedError
22
22
  end
23
23
 
24
- def register_worker(queue, clazz)
24
+ def register_worker(_queue, _clazz)
25
25
  # must register the worker as a consumer of messages from queue
26
26
  fail NotImplementedError
27
27
  end
28
28
 
29
- def workers(queue)
29
+ def workers(_queue)
30
30
  # must return the list of workers registered for queue, or []
31
31
  fail NotImplementedError
32
32
  end
@@ -1,5 +1,5 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+
2
+ lib = File.expand_path('lib', __dir__)
3
3
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'shoryuken/version'
5
5
 
@@ -13,15 +13,15 @@ Gem::Specification.new do |spec|
13
13
  spec.license = 'LGPL-3.0'
14
14
 
15
15
  spec.files = `git ls-files -z`.split("\x0")
16
- spec.executables = %w(shoryuken)
16
+ spec.executables = %w[shoryuken]
17
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
18
  spec.require_paths = ['lib']
19
19
 
20
20
  spec.add_development_dependency 'bundler', '~> 1.6'
21
+ spec.add_development_dependency 'dotenv'
22
+ spec.add_development_dependency 'pry-byebug'
21
23
  spec.add_development_dependency 'rake'
22
24
  spec.add_development_dependency 'rspec'
23
- spec.add_development_dependency 'pry-byebug'
24
- spec.add_development_dependency 'dotenv'
25
25
 
26
26
  spec.add_dependency 'aws-sdk-core', '>= 2'
27
27
  spec.add_dependency 'concurrent-ruby'
@@ -4,7 +4,7 @@ require 'shoryuken/launcher'
4
4
  require 'securerandom'
5
5
 
6
6
  RSpec.describe Shoryuken::Launcher do
7
- describe 'Consuming messages', slow: :true do
7
+ describe 'Consuming messages', slow: true do
8
8
  before do
9
9
  Aws.config[:stub_responses] = false
10
10
  Aws.config[:region] = 'us-east-1'
@@ -85,7 +85,7 @@ RSpec.describe Shoryuken::Launcher do
85
85
 
86
86
  shoryuken_options auto_delete: true
87
87
 
88
- def perform(sqs_msg, body)
88
+ def perform(sqs_msg, _body)
89
89
  @@received_messages += Array(sqs_msg).size
90
90
  end
91
91
 
@@ -69,8 +69,8 @@ RSpec.describe Shoryuken::BodyParser do
69
69
  end
70
70
 
71
71
  specify do
72
- expect { described_class.parse(TestWorker, sqs_msg) }.
73
- to raise_error(JSON::ParserError, /unexpected token at 'invalid JSON'/)
72
+ expect { described_class.parse(TestWorker, sqs_msg) }
73
+ .to raise_error(JSON::ParserError, /unexpected token at 'invalid JSON'/)
74
74
  end
75
75
  end
76
76
 
@@ -12,7 +12,7 @@ RSpec.describe Shoryuken::Client do
12
12
  end
13
13
 
14
14
  it 'memoizes queues' do
15
- sqs.stub_responses(:get_queue_url, { queue_url: queue_url }, { queue_url: 'xyz' })
15
+ sqs.stub_responses(:get_queue_url, { queue_url: queue_url }, queue_url: 'xyz')
16
16
 
17
17
  expect(Shoryuken::Client.queues(queue_name).url).to eq queue_url
18
18
  expect(Shoryuken::Client.queues(queue_name).url).to eq queue_url
@@ -10,7 +10,7 @@ RSpec.describe 'Core Extensions' do
10
10
 
11
11
  describe '#symbolize_keys' do
12
12
  it 'converts keys into symbols' do
13
- expect({ :key1 => 'value1', 'key2' => 'value2' }.symbolize_keys).to eq(:key1 => 'value1', key2: 'value2')
13
+ expect({ :key1 => 'value1', 'key2' => 'value2' }.symbolize_keys).to eq(key1: 'value1', key2: 'value2')
14
14
  end
15
15
  end
16
16
 
@@ -20,11 +20,11 @@ RSpec.describe 'Core Extensions' do
20
20
  'key2' => 'value2',
21
21
  'key3' => {
22
22
  'key31' => { 'key311' => 'value311' },
23
- 'key32' => 'value32' } }.deep_symbolize_keys).to eq({ :key1 => 'value1',
24
- :key2 => 'value2',
25
- :key3 => { :key31 =>
26
- { :key311 => 'value311' },
27
- :key32 => 'value32' } })
23
+ 'key32' => 'value32'
24
+ } }.deep_symbolize_keys).to eq(key1: 'value1',
25
+ key2: 'value2',
26
+ key3: { key31: { key311: 'value311' },
27
+ key32: 'value32' })
28
28
  end
29
29
  end
30
30
  end
@@ -43,12 +43,10 @@ RSpec.describe Shoryuken::DefaultWorkerRegistry do
43
43
  end
44
44
 
45
45
  describe 'a registry with workers is handling messages' do
46
- def build_message(queue, explicit_worker = nil)
46
+ def build_message(_queue, explicit_worker = nil)
47
47
  attributes = {}
48
48
 
49
- if explicit_worker
50
- attributes['shoryuken_class'] = { string_value: explicit_worker.to_s, data_type: 'String' }
51
- end
49
+ attributes['shoryuken_class'] = { string_value: explicit_worker.to_s, data_type: 'String' } if explicit_worker
52
50
 
53
51
  double(Shoryuken::Message,
54
52
  body: 'test',
@@ -18,7 +18,7 @@ RSpec.describe Shoryuken::EnvironmentLoader do
18
18
  Shoryuken.options[:queues] = ['queue1', ['queue2', 2]]
19
19
  subject.load
20
20
 
21
- expect(Shoryuken.groups['default'][:queues]).to eq(%w(queue1 queue2 queue2))
21
+ expect(Shoryuken.groups['default'][:queues]).to eq(%w[queue1 queue2 queue2])
22
22
  end
23
23
  end
24
24
 
@@ -42,13 +42,13 @@ RSpec.describe Shoryuken::EnvironmentLoader do
42
42
  Shoryuken.options[:queues] = ['queue1', ['queue2', 2]]
43
43
 
44
44
  Shoryuken.options[:groups] = {
45
- 'group1' => { queues: %w(group1_queue1 group1_queue2) }
45
+ 'group1' => { queues: %w[group1_queue1 group1_queue2] }
46
46
  }
47
47
 
48
48
  subject.load
49
49
 
50
- expect(Shoryuken.groups['default'][:queues]).to eq(%w(test_queue1 test_queue2 test_queue2))
51
- expect(Shoryuken.groups['group1'][:queues]).to eq(%w(test_group1_queue1 test_group1_queue2))
50
+ expect(Shoryuken.groups['default'][:queues]).to eq(%w[test_queue1 test_queue2 test_queue2])
51
+ expect(Shoryuken.groups['group1'][:queues]).to eq(%w[test_group1_queue1 test_group1_queue2])
52
52
  end
53
53
  end
54
54
  end
@@ -9,13 +9,13 @@ RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter do
9
9
 
10
10
  before do
11
11
  allow(Shoryuken::Client).to receive(:queues).with(job.queue_name).and_return(queue)
12
- allow(job).to receive(:serialize).and_return({
13
- 'job_class' => 'Worker',
12
+ allow(job).to receive(:serialize).and_return(
13
+ 'job_class' => 'Worker',
14
14
  'job_id' => job.id,
15
15
  'queue_name' => job.queue_name,
16
16
  'arguments' => nil,
17
17
  'locale' => nil
18
- })
18
+ )
19
19
  end
20
20
 
21
21
  describe '#enqueue' do
@@ -79,7 +79,7 @@ RSpec.describe Shoryuken::Manager do
79
79
 
80
80
  context 'when batch' do
81
81
  specify do
82
- messages = %w(test1 test2 test3)
82
+ messages = %w[test1 test2 test3]
83
83
  q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
84
84
 
85
85
  expect(fetcher).to receive(:fetch).with(q, described_class::BATCH_LIMIT).and_return(messages)
@@ -7,7 +7,7 @@ RSpec.describe Shoryuken::Middleware::Chain do
7
7
  @recorder = recorder
8
8
  end
9
9
 
10
- def call(*args)
10
+ def call(*_args)
11
11
  @recorder << [@name, 'before']
12
12
  yield
13
13
  @recorder << [@name, 'after']
@@ -39,7 +39,7 @@ RSpec.describe Shoryuken::Middleware::Chain do
39
39
  final_action = nil
40
40
  subject.invoke { final_action = true }
41
41
  expect(final_action).to eq true
42
- expect(recorder).to eq [%w(custom before), %w(custom after)]
42
+ expect(recorder).to eq [%w[custom before], %w[custom after]]
43
43
  end
44
44
 
45
45
  class NonYieldingMiddleware
@@ -6,9 +6,9 @@ describe Shoryuken::Middleware::Server::AutoDelete do
6
6
 
7
7
  def build_message
8
8
  double Shoryuken::Message,
9
- queue_url: queue,
10
- body: 'test',
11
- receipt_handle: SecureRandom.uuid
9
+ queue_url: queue,
10
+ body: 'test',
11
+ receipt_handle: SecureRandom.uuid
12
12
  end
13
13
 
14
14
  let(:sqs_msg) { build_message }
@@ -21,7 +21,8 @@ describe Shoryuken::Middleware::Server::AutoDelete do
21
21
  TestWorker.get_shoryuken_options['auto_delete'] = true
22
22
 
23
23
  expect(sqs_queue).to receive(:delete_messages).with(entries: [
24
- { id: '0', receipt_handle: sqs_msg.receipt_handle }])
24
+ { id: '0', receipt_handle: sqs_msg.receipt_handle }
25
+ ])
25
26
 
26
27
  subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
27
28
  end
@@ -35,9 +36,10 @@ describe Shoryuken::Middleware::Server::AutoDelete do
35
36
  sqs_msgs = [sqs_msg, sqs_msg2, sqs_msg3]
36
37
 
37
38
  expect(sqs_queue).to receive(:delete_messages).with(entries: [
38
- { id: '0', receipt_handle: sqs_msg.receipt_handle },
39
- { id: '1', receipt_handle: sqs_msg2.receipt_handle },
40
- { id: '2', receipt_handle: sqs_msg3.receipt_handle }])
39
+ { id: '0', receipt_handle: sqs_msg.receipt_handle },
40
+ { id: '1', receipt_handle: sqs_msg2.receipt_handle },
41
+ { id: '2', receipt_handle: sqs_msg3.receipt_handle }
42
+ ])
41
43
 
42
44
  subject.call(TestWorker.new, queue, sqs_msgs, [sqs_msg.body, sqs_msg2.body, sqs_msg3.body]) {}
43
45
  end
@@ -18,9 +18,9 @@ RSpec.describe Shoryuken::Middleware::Server::AutoExtendVisibility do
18
18
  end
19
19
  end
20
20
 
21
- def run_and_raise(worker, queue, sqs_msg, error_class)
21
+ def run_and_raise(worker, queue, sqs_msg)
22
22
  Shoryuken::Middleware::Server::AutoExtendVisibility.new.call(worker, queue, sqs_msg, sqs_msg.body) do
23
- raise error_class.new
23
+ raise
24
24
  end
25
25
  end
26
26
  end
@@ -53,7 +53,7 @@ RSpec.describe Shoryuken::Middleware::Server::AutoExtendVisibility do
53
53
  allow(sqs_msg).to receive(:queue) { sqs_queue }
54
54
  expect(sqs_msg).to_not receive(:change_visibility)
55
55
 
56
- expect { Runner.new.run_and_raise(TestWorker.new, queue, sqs_msg, StandardError) }.to raise_error(StandardError)
56
+ expect { Runner.new.run_and_raise(TestWorker.new, queue, sqs_msg) }.to raise_error
57
57
  end
58
58
 
59
59
  it 'does not extend message visibility if auto_visibility_timeout is not true' do
@@ -1,11 +1,13 @@
1
1
  require 'spec_helper'
2
2
 
3
- # rubocop:disable Metrics/BlockLength, Metrics/BlockDelimiters
3
+ # rubocop:disable /BlockLength, Metrics/
4
4
  RSpec.describe Shoryuken::Middleware::Server::ExponentialBackoffRetry do
5
5
  let(:queue) { 'default' }
6
6
  let(:sqs_queue) { double Shoryuken::Queue }
7
- let(:sqs_msg) { double Shoryuken::Message, queue_url: queue, body: 'test', receipt_handle: SecureRandom.uuid,
8
- attributes: {'ApproximateReceiveCount' => 1}, message_id: SecureRandom.uuid }
7
+ let(:sqs_msg) {
8
+ double Shoryuken::Message, queue_url: queue, body: 'test', receipt_handle: SecureRandom.uuid,
9
+ attributes: { 'ApproximateReceiveCount' => 1 }, message_id: SecureRandom.uuid
10
+ }
9
11
 
10
12
  before do
11
13
  allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
@@ -12,8 +12,8 @@ RSpec.describe Shoryuken::Options do
12
12
  described_class.add_queue('queue1', 1, 'group1')
13
13
  described_class.add_queue('queue2', 2, 'group2')
14
14
 
15
- expect(described_class.groups['group1'][:queues]).to eq(%w(queue1))
16
- expect(described_class.groups['group2'][:queues]).to eq(%w(queue2 queue2))
15
+ expect(described_class.groups['group1'][:queues]).to eq(%w[queue1])
16
+ expect(described_class.groups['group2'][:queues]).to eq(%w[queue2 queue2])
17
17
  end
18
18
  end
19
19
 
@@ -28,7 +28,7 @@ RSpec.describe Shoryuken::Options do
28
28
  described_class.add_queue('queue1', 1, 'group1')
29
29
  described_class.add_queue('queue2', 2, 'group2')
30
30
 
31
- expect(described_class.ungrouped_queues).to eq(%w(queue1 queue2 queue2))
31
+ expect(described_class.ungrouped_queues).to eq(%w[queue1 queue2 queue2])
32
32
  end
33
33
  end
34
34
 
@@ -45,7 +45,7 @@ RSpec.describe Shoryuken::Options do
45
45
 
46
46
  expect(Shoryuken.sqs_client_receive_message_opts).to eq(
47
47
  'default' => { test: 1 },
48
- 'group1' => { test: 2 },
48
+ 'group1' => { test: 2 }
49
49
  )
50
50
  end
51
51
  end
@@ -93,7 +93,7 @@ RSpec.describe Shoryuken::Options do
93
93
 
94
94
  def perform(sqs_msg, body); end
95
95
  end
96
- }.to raise_error("Could not register BatchableWorker for default, because TestWorker is already registered for this queue, " \
96
+ }.to raise_error('Could not register BatchableWorker for default, because TestWorker is already registered for this queue, ' \
97
97
  "and Shoryuken doesn't support a batchable worker for a queue with multiple workers")
98
98
  end
99
99
  end
@@ -4,7 +4,7 @@ RSpec.describe Shoryuken::Polling::StrictPriority do
4
4
  let(:queue1) { 'shoryuken' }
5
5
  let(:queue2) { 'uppercut' }
6
6
  let(:queue3) { 'other' }
7
- let(:queues) { Array.new }
7
+ let(:queues) { [] }
8
8
  subject { Shoryuken::Polling::StrictPriority.new(queues) }
9
9
 
10
10
  describe '#next_queue' do
@@ -3,7 +3,7 @@ require 'spec_helper'
3
3
  RSpec.describe Shoryuken::Polling::WeightedRoundRobin do
4
4
  let(:queue1) { 'shoryuken' }
5
5
  let(:queue2) { 'uppercut' }
6
- let(:queues) { Array.new }
6
+ let(:queues) { [] }
7
7
  subject { Shoryuken::Polling::WeightedRoundRobin.new(queues) }
8
8
 
9
9
  describe '#next_queue' do
@@ -38,7 +38,7 @@ RSpec.describe Shoryuken::Processor do
38
38
  let(:queue) { 'worker_called_middleware' }
39
39
 
40
40
  class WorkerCalledMiddleware
41
- def call(worker, queue, sqs_msg, body)
41
+ def call(worker, queue, sqs_msg, _body)
42
42
  # called is defined with `allow(...).to receive(...)`
43
43
  worker.called(sqs_msg, queue)
44
44
  yield