shoryuken 5.0.5 → 6.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.devcontainer/Dockerfile +17 -0
- data/.devcontainer/base.Dockerfile +43 -0
- data/.devcontainer/devcontainer.json +35 -0
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/specs.yml +65 -0
- data/.github/workflows/stale.yml +20 -0
- data/.gitignore +1 -1
- data/.reek.yml +5 -0
- data/.rubocop.yml +1 -1
- data/Appraisals +42 -0
- data/CHANGELOG.md +114 -0
- data/Gemfile +8 -3
- data/README.md +41 -1
- data/Rakefile +15 -1
- data/bin/cli/sqs.rb +51 -6
- data/gemfiles/.gitignore +1 -0
- data/gemfiles/aws_sdk_core_2.gemfile +21 -0
- data/gemfiles/rails_4_2.gemfile +20 -0
- data/gemfiles/rails_5_2.gemfile +21 -0
- data/gemfiles/rails_6_0.gemfile +21 -0
- data/gemfiles/rails_6_1.gemfile +21 -0
- data/gemfiles/rails_7_0.gemfile +22 -0
- data/lib/shoryuken/default_exception_handler.rb +10 -0
- data/lib/shoryuken/environment_loader.rb +22 -4
- data/lib/shoryuken/extensions/active_job_adapter.rb +30 -20
- data/lib/shoryuken/extensions/active_job_extensions.rb +38 -0
- data/lib/shoryuken/launcher.rb +26 -3
- data/lib/shoryuken/logging.rb +2 -2
- data/lib/shoryuken/manager.rb +50 -14
- data/lib/shoryuken/message.rb +11 -28
- data/lib/shoryuken/options.rb +6 -3
- data/lib/shoryuken/polling/base.rb +2 -0
- data/lib/shoryuken/polling/strict_priority.rb +8 -0
- data/lib/shoryuken/polling/weighted_round_robin.rb +9 -0
- data/lib/shoryuken/processor.rb +1 -2
- data/lib/shoryuken/queue.rb +5 -3
- data/lib/shoryuken/runner.rb +4 -3
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken.rb +8 -0
- data/shoryuken.gemspec +1 -2
- data/spec/integration/launcher_spec.rb +29 -2
- data/spec/shared_examples_for_active_job.rb +230 -11
- data/spec/shoryuken/default_exception_handler_spec.rb +71 -0
- data/spec/shoryuken/environment_loader_spec.rb +62 -9
- data/spec/shoryuken/extensions/active_job_adapter_spec.rb +1 -1
- data/spec/shoryuken/extensions/active_job_base_spec.rb +84 -0
- data/spec/shoryuken/extensions/active_job_concurrent_send_adapter_spec.rb +4 -0
- data/spec/shoryuken/extensions/active_job_wrapper_spec.rb +20 -0
- data/spec/shoryuken/fetcher_spec.rb +12 -12
- data/spec/shoryuken/launcher_spec.rb +105 -0
- data/spec/shoryuken/manager_spec.rb +61 -1
- data/spec/shoryuken/polling/strict_priority_spec.rb +10 -0
- data/spec/shoryuken/polling/weighted_round_robin_spec.rb +35 -0
- data/spec/shoryuken/queue_spec.rb +10 -5
- data/spec/shoryuken/worker/default_executor_spec.rb +48 -48
- data/spec/shoryuken_spec.rb +9 -0
- data/spec/spec_helper.rb +7 -9
- metadata +32 -24
- data/.travis.yml +0 -30
- data/Gemfile.aws-sdk-core-v2 +0 -13
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_job'
|
3
|
+
require 'shoryuken/extensions/active_job_extensions'
|
4
|
+
require 'shoryuken/extensions/active_job_adapter'
|
5
|
+
|
6
|
+
RSpec.describe ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper do
|
7
|
+
subject { described_class.new }
|
8
|
+
|
9
|
+
describe '#perform' do
|
10
|
+
it 'sets executions to reflect approximate receive count' do
|
11
|
+
attributes = { 'ApproximateReceiveCount' => '42' }
|
12
|
+
sqs_msg = double Shoryuken::Message, attributes: attributes
|
13
|
+
job_hash = { 'arguments' => [1, 2, 3] }
|
14
|
+
job_hash_with_executions = { 'arguments' => [1, 2, 3], 'executions' => 41 }
|
15
|
+
expect(ActiveJob::Base).to receive(:execute).with(job_hash_with_executions)
|
16
|
+
|
17
|
+
subject.perform sqs_msg, job_hash
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -28,12 +28,12 @@ RSpec.describe Shoryuken::Fetcher do
|
|
28
28
|
|
29
29
|
Shoryuken.sqs_client_receive_message_opts[group] = { wait_time_seconds: 10 }
|
30
30
|
|
31
|
-
expect(queue).to receive(:receive_messages).with(
|
31
|
+
expect(queue).to receive(:receive_messages).with({
|
32
32
|
wait_time_seconds: 10,
|
33
33
|
max_number_of_messages: limit,
|
34
34
|
message_attribute_names: ['All'],
|
35
35
|
attribute_names: ['All']
|
36
|
-
).and_return([])
|
36
|
+
}).and_return([])
|
37
37
|
|
38
38
|
subject.fetch(queue_config, limit)
|
39
39
|
end
|
@@ -62,11 +62,11 @@ RSpec.describe Shoryuken::Fetcher do
|
|
62
62
|
|
63
63
|
Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 1 }
|
64
64
|
|
65
|
-
expect(queue).to receive(:receive_messages).with(
|
65
|
+
expect(queue).to receive(:receive_messages).with({
|
66
66
|
max_number_of_messages: 1,
|
67
67
|
message_attribute_names: ['All'],
|
68
68
|
attribute_names: ['All']
|
69
|
-
).and_return([])
|
69
|
+
}).and_return([])
|
70
70
|
|
71
71
|
subject.fetch(queue_config, limit)
|
72
72
|
end
|
@@ -78,11 +78,11 @@ RSpec.describe Shoryuken::Fetcher do
|
|
78
78
|
|
79
79
|
Shoryuken.sqs_client_receive_message_opts[queue_name] = { max_number_of_messages: 20 }
|
80
80
|
|
81
|
-
expect(queue).to receive(:receive_messages).with(
|
81
|
+
expect(queue).to receive(:receive_messages).with({
|
82
82
|
max_number_of_messages: limit,
|
83
83
|
message_attribute_names: ['All'],
|
84
84
|
attribute_names: ['All']
|
85
|
-
).and_return([])
|
85
|
+
}).and_return([])
|
86
86
|
|
87
87
|
subject.fetch(queue_config, limit)
|
88
88
|
end
|
@@ -93,9 +93,9 @@ RSpec.describe Shoryuken::Fetcher do
|
|
93
93
|
|
94
94
|
specify do
|
95
95
|
allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
96
|
-
expect(queue).to receive(:receive_messages).with(
|
96
|
+
expect(queue).to receive(:receive_messages).with({
|
97
97
|
max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']
|
98
|
-
).and_return([])
|
98
|
+
}).and_return([])
|
99
99
|
|
100
100
|
subject.fetch(queue_config, limit)
|
101
101
|
end
|
@@ -109,9 +109,9 @@ RSpec.describe Shoryuken::Fetcher do
|
|
109
109
|
# see https://github.com/phstc/shoryuken/pull/530
|
110
110
|
|
111
111
|
allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
112
|
-
expect(queue).to receive(:receive_messages).with(
|
112
|
+
expect(queue).to receive(:receive_messages).with({
|
113
113
|
max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']
|
114
|
-
).and_return([])
|
114
|
+
}).and_return([])
|
115
115
|
|
116
116
|
subject.fetch(queue_config, limit)
|
117
117
|
end
|
@@ -123,9 +123,9 @@ RSpec.describe Shoryuken::Fetcher do
|
|
123
123
|
allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
124
124
|
allow(Shoryuken.worker_registry).to receive(:batch_receive_messages?).with(queue.name).and_return(true)
|
125
125
|
|
126
|
-
expect(queue).to receive(:receive_messages).with(
|
126
|
+
expect(queue).to receive(:receive_messages).with({
|
127
127
|
max_number_of_messages: limit, attribute_names: ['All'], message_attribute_names: ['All']
|
128
|
-
).and_return([])
|
128
|
+
}).and_return([])
|
129
129
|
|
130
130
|
subject.fetch(queue_config, limit)
|
131
131
|
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'shoryuken/launcher'
|
3
|
+
|
4
|
+
RSpec.describe Shoryuken::Launcher do
|
5
|
+
let(:executor) do
|
6
|
+
# We can't use Concurrent.global_io_executor in these tests since once you
|
7
|
+
# shut down a thread pool, you can't start it back up. Instead, we create
|
8
|
+
# one new thread pool executor for each spec. We use a new
|
9
|
+
# CachedThreadPool, since that most closely resembles
|
10
|
+
# Concurrent.global_io_executor
|
11
|
+
Concurrent::CachedThreadPool.new auto_terminate: true
|
12
|
+
end
|
13
|
+
|
14
|
+
let(:first_group_manager) { double(:first_group_manager, group: 'first_group') }
|
15
|
+
let(:second_group_manager) { double(:second_group_manager, group: 'second_group') }
|
16
|
+
let(:first_queue) { "launcher_spec_#{SecureRandom.uuid}" }
|
17
|
+
let(:second_queue) { "launcher_spec_#{SecureRandom.uuid}" }
|
18
|
+
|
19
|
+
before do
|
20
|
+
Shoryuken.add_group('first_group', 1)
|
21
|
+
Shoryuken.add_group('second_group', 1)
|
22
|
+
Shoryuken.add_queue(first_queue, 1, 'first_group')
|
23
|
+
Shoryuken.add_queue(second_queue, 1, 'second_group')
|
24
|
+
allow(Shoryuken).to receive(:launcher_executor).and_return(executor)
|
25
|
+
allow(Shoryuken::Manager).to receive(:new).with('first_group', any_args).and_return(first_group_manager)
|
26
|
+
allow(Shoryuken::Manager).to receive(:new).with('second_group', any_args).and_return(second_group_manager)
|
27
|
+
allow(first_group_manager).to receive(:running?).and_return(true)
|
28
|
+
allow(second_group_manager).to receive(:running?).and_return(true)
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#healthy?' do
|
32
|
+
context 'when all groups have managers' do
|
33
|
+
context 'when all managers are running' do
|
34
|
+
it 'returns true' do
|
35
|
+
expect(subject.healthy?).to be true
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context 'when one manager is not running' do
|
40
|
+
before do
|
41
|
+
allow(second_group_manager).to receive(:running?).and_return(false)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'returns false' do
|
45
|
+
expect(subject.healthy?).to be false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'when all groups do not have managers' do
|
51
|
+
before do
|
52
|
+
allow(second_group_manager).to receive(:group).and_return('some_random_group')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'returns false' do
|
56
|
+
expect(subject.healthy?).to be false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe '#stop' do
|
62
|
+
before do
|
63
|
+
allow(first_group_manager).to receive(:stop_new_dispatching)
|
64
|
+
allow(first_group_manager).to receive(:await_dispatching_in_progress)
|
65
|
+
allow(second_group_manager).to receive(:stop_new_dispatching)
|
66
|
+
allow(second_group_manager).to receive(:await_dispatching_in_progress)
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'fires quiet, shutdown and stopped event' do
|
70
|
+
allow(subject).to receive(:fire_event)
|
71
|
+
subject.stop
|
72
|
+
expect(subject).to have_received(:fire_event).with(:quiet, true)
|
73
|
+
expect(subject).to have_received(:fire_event).with(:shutdown, true)
|
74
|
+
expect(subject).to have_received(:fire_event).with(:stopped)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'stops the managers' do
|
78
|
+
subject.stop
|
79
|
+
expect(first_group_manager).to have_received(:stop_new_dispatching)
|
80
|
+
expect(second_group_manager).to have_received(:stop_new_dispatching)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
describe '#stop!' do
|
85
|
+
before do
|
86
|
+
allow(first_group_manager).to receive(:stop_new_dispatching)
|
87
|
+
allow(first_group_manager).to receive(:await_dispatching_in_progress)
|
88
|
+
allow(second_group_manager).to receive(:stop_new_dispatching)
|
89
|
+
allow(second_group_manager).to receive(:await_dispatching_in_progress)
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'fires shutdown and stopped event' do
|
93
|
+
allow(subject).to receive(:fire_event)
|
94
|
+
subject.stop!
|
95
|
+
expect(subject).to have_received(:fire_event).with(:shutdown, true)
|
96
|
+
expect(subject).to have_received(:fire_event).with(:stopped)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'stops the managers' do
|
100
|
+
subject.stop!
|
101
|
+
expect(first_group_manager).to have_received(:stop_new_dispatching)
|
102
|
+
expect(second_group_manager).to have_received(:stop_new_dispatching)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -15,7 +15,7 @@ RSpec.describe Shoryuken::Manager do
|
|
15
15
|
let(:concurrency) { 1 }
|
16
16
|
let(:executor) { Concurrent::ImmediateExecutor.new }
|
17
17
|
|
18
|
-
subject { Shoryuken::Manager.new(fetcher, polling_strategy, concurrency, executor) }
|
18
|
+
subject { Shoryuken::Manager.new('default', fetcher, polling_strategy, concurrency, executor) }
|
19
19
|
|
20
20
|
before do
|
21
21
|
allow(fetcher).to receive(:fetch).and_return([])
|
@@ -71,6 +71,13 @@ RSpec.describe Shoryuken::Manager do
|
|
71
71
|
|
72
72
|
expect(fetcher).to receive(:fetch).with(q, concurrency).and_return(messages)
|
73
73
|
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
74
|
+
expect(subject).to receive(:fire_event).with(:utilization_update,
|
75
|
+
false,
|
76
|
+
{
|
77
|
+
group: 'default',
|
78
|
+
busy_processors: 1,
|
79
|
+
max_processors: 1
|
80
|
+
})
|
74
81
|
expect(Shoryuken::Processor).to receive(:process).with(q, message)
|
75
82
|
expect(Shoryuken.logger).to receive(:info).never
|
76
83
|
|
@@ -99,6 +106,13 @@ RSpec.describe Shoryuken::Manager do
|
|
99
106
|
q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
|
100
107
|
|
101
108
|
expect(fetcher).to receive(:fetch).with(q, described_class::BATCH_LIMIT).and_return(messages)
|
109
|
+
expect(subject).to receive(:fire_event).with(:utilization_update,
|
110
|
+
false,
|
111
|
+
{
|
112
|
+
group: 'default',
|
113
|
+
busy_processors: 1,
|
114
|
+
max_processors: 1
|
115
|
+
})
|
102
116
|
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
103
117
|
allow(subject).to receive(:batched_queue?).with(q).and_return(true)
|
104
118
|
expect(Shoryuken::Processor).to receive(:process).with(q, messages)
|
@@ -139,4 +153,50 @@ RSpec.describe Shoryuken::Manager do
|
|
139
153
|
subject.send(:dispatch_single_messages, q)
|
140
154
|
end
|
141
155
|
end
|
156
|
+
|
157
|
+
describe '#processor_done' do
|
158
|
+
let(:sqs_queue) { double Shoryuken::Queue }
|
159
|
+
|
160
|
+
before do
|
161
|
+
allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
|
162
|
+
end
|
163
|
+
|
164
|
+
context 'when queue.fifo? is true' do
|
165
|
+
it 'calls message_processed on strategy' do
|
166
|
+
expect(sqs_queue).to receive(:fifo?).and_return(true)
|
167
|
+
expect(polling_strategy).to receive(:message_processed).with(queue)
|
168
|
+
subject.send(:processor_done, queue)
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
context 'when queue.fifo? is false' do
|
173
|
+
it 'does not call message_processed on strategy' do
|
174
|
+
expect(sqs_queue).to receive(:fifo?).and_return(false)
|
175
|
+
expect(polling_strategy).to_not receive(:message_processed)
|
176
|
+
subject.send(:processor_done, queue)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
describe '#running?' do
|
182
|
+
context 'when the executor is running' do
|
183
|
+
before do
|
184
|
+
allow(executor).to receive(:running?).and_return(true)
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'returns true' do
|
188
|
+
expect(subject.running?).to be true
|
189
|
+
end
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'when the executor is not running' do
|
193
|
+
before do
|
194
|
+
allow(executor).to receive(:running?).and_return(false)
|
195
|
+
end
|
196
|
+
|
197
|
+
it 'returns false' do
|
198
|
+
expect(subject.running?).to be false
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
142
202
|
end
|
@@ -145,4 +145,14 @@ RSpec.describe Shoryuken::Polling::StrictPriority do
|
|
145
145
|
expect(subject.next_queue).to eq(queue3)
|
146
146
|
end
|
147
147
|
end
|
148
|
+
|
149
|
+
describe '#message_processed' do
|
150
|
+
it 'removes paused queue, adds to active queues' do
|
151
|
+
strategy = Shoryuken::Polling::StrictPriority.new([queue1, queue2])
|
152
|
+
strategy.send(:pause, queue1)
|
153
|
+
expect(strategy.active_queues).to eq([[queue2, 1]])
|
154
|
+
strategy.message_processed(queue1)
|
155
|
+
expect(strategy.active_queues).to eq([[queue1, 2], [queue2, 1]])
|
156
|
+
end
|
157
|
+
end
|
148
158
|
end
|
@@ -104,4 +104,39 @@ RSpec.describe Shoryuken::Polling::WeightedRoundRobin do
|
|
104
104
|
expect(subject.delay).to eq(1.0)
|
105
105
|
end
|
106
106
|
end
|
107
|
+
|
108
|
+
describe '#message_processed' do
|
109
|
+
it 'removes delay from paused queue' do
|
110
|
+
queues << queue1
|
111
|
+
queues << queue2
|
112
|
+
|
113
|
+
expect(subject.next_queue).to eq(queue1)
|
114
|
+
subject.messages_found(queue1, 0) # pauses queue1
|
115
|
+
|
116
|
+
expect(subject.active_queues).to eq([[queue2, 1]])
|
117
|
+
|
118
|
+
subject.message_processed(queue1) # marks queue1 to be unpaused
|
119
|
+
|
120
|
+
expect(subject.next_queue).to eq(queue2) # implicitly unpauses queue1
|
121
|
+
expect(subject.active_queues).to eq([[queue1, 1], [queue2, 1]])
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'preserves weight of queues when unpausing' do
|
125
|
+
queues << queue1
|
126
|
+
queues << queue1
|
127
|
+
queues << queue2
|
128
|
+
|
129
|
+
expect(subject.next_queue).to eq(queue1)
|
130
|
+
subject.messages_found(queue1, 1)
|
131
|
+
|
132
|
+
expect(subject.next_queue).to eq(queue2)
|
133
|
+
subject.messages_found(queue2, 0) # pauses queue2
|
134
|
+
|
135
|
+
expect(subject.active_queues).to eq([[queue1, 2]])
|
136
|
+
subject.message_processed(queue2) # marks queue2 to be unpaused
|
137
|
+
|
138
|
+
expect(subject.next_queue).to eq(queue1) # implicitly unpauses queue2
|
139
|
+
expect(subject.active_queues).to eq([[queue1, 2], [queue2, 1]])
|
140
|
+
end
|
141
|
+
end
|
107
142
|
end
|
@@ -80,7 +80,8 @@ RSpec.describe Shoryuken::Queue do
|
|
80
80
|
end
|
81
81
|
|
82
82
|
it 'deletes' do
|
83
|
-
expect(sqs).to receive(:delete_message_batch).with(entries: entries,
|
83
|
+
expect(sqs).to receive(:delete_message_batch).with({ entries: entries,
|
84
|
+
queue_url: queue_url }).and_return(double(failed: []))
|
84
85
|
|
85
86
|
subject.delete_messages(entries: entries)
|
86
87
|
end
|
@@ -91,7 +92,8 @@ RSpec.describe Shoryuken::Queue do
|
|
91
92
|
logger = double 'Logger'
|
92
93
|
|
93
94
|
expect(sqs).to(
|
94
|
-
receive(:delete_message_batch).with(entries: entries,
|
95
|
+
receive(:delete_message_batch).with({ entries: entries,
|
96
|
+
queue_url: queue_url }).and_return(double(failed: [failure]))
|
95
97
|
)
|
96
98
|
expect(subject).to receive(:logger).and_return(logger)
|
97
99
|
expect(logger).to receive(:error)
|
@@ -157,7 +159,8 @@ RSpec.describe Shoryuken::Queue do
|
|
157
159
|
it 'accepts SQS request parameters' do
|
158
160
|
# https://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#send_message_batch-instance_method
|
159
161
|
expect(sqs).to(
|
160
|
-
receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1' },
|
162
|
+
receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1' },
|
163
|
+
{ id: '1', message_body: 'msg2' }]))
|
161
164
|
)
|
162
165
|
|
163
166
|
subject.send_messages(entries: [{ id: '0', message_body: 'msg1' }, { id: '1', message_body: 'msg2' }])
|
@@ -286,7 +289,8 @@ RSpec.describe Shoryuken::Queue do
|
|
286
289
|
Shoryuken.cache_visibility_timeout = false
|
287
290
|
|
288
291
|
expect(sqs).to(
|
289
|
-
receive(:get_queue_attributes).with(queue_url: queue_url,
|
292
|
+
receive(:get_queue_attributes).with(queue_url: queue_url,
|
293
|
+
attribute_names: ['All']).and_return(attribute_response).exactly(3).times
|
290
294
|
)
|
291
295
|
expect(subject.visibility_timeout).to eq(30)
|
292
296
|
expect(subject.visibility_timeout).to eq(30)
|
@@ -299,7 +303,8 @@ RSpec.describe Shoryuken::Queue do
|
|
299
303
|
Shoryuken.cache_visibility_timeout = true
|
300
304
|
|
301
305
|
expect(sqs).to(
|
302
|
-
receive(:get_queue_attributes).with(queue_url: queue_url,
|
306
|
+
receive(:get_queue_attributes).with({ queue_url: queue_url,
|
307
|
+
attribute_names: ['All'] }).and_return(attribute_response).once
|
303
308
|
)
|
304
309
|
expect(subject.visibility_timeout).to eq(30)
|
305
310
|
expect(subject.visibility_timeout).to eq(30)
|
@@ -10,16 +10,16 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
|
|
10
10
|
|
11
11
|
describe '.perform_in' do
|
12
12
|
it 'delays a message' do
|
13
|
-
expect(sqs_queue).to receive(:send_message).with(
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
13
|
+
expect(sqs_queue).to receive(:send_message).with({
|
14
|
+
message_attributes: {
|
15
|
+
'shoryuken_class' => {
|
16
|
+
string_value: TestWorker.to_s,
|
17
|
+
data_type: 'String'
|
18
|
+
}
|
19
|
+
},
|
20
|
+
message_body: 'message',
|
21
|
+
delay_seconds: 60
|
22
|
+
})
|
23
23
|
|
24
24
|
TestWorker.perform_in(60, 'message')
|
25
25
|
end
|
@@ -33,16 +33,16 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
|
|
33
33
|
|
34
34
|
describe '.perform_at' do
|
35
35
|
it 'delays a message' do
|
36
|
-
expect(sqs_queue).to receive(:send_message).with(
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
36
|
+
expect(sqs_queue).to receive(:send_message).with({
|
37
|
+
message_attributes: {
|
38
|
+
'shoryuken_class' => {
|
39
|
+
string_value: TestWorker.to_s,
|
40
|
+
data_type: 'String'
|
41
|
+
}
|
42
|
+
},
|
43
|
+
message_body: 'message',
|
44
|
+
delay_seconds: 60
|
45
|
+
})
|
46
46
|
|
47
47
|
TestWorker.perform_in(Time.now + 60, 'message')
|
48
48
|
end
|
@@ -56,30 +56,30 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
|
|
56
56
|
|
57
57
|
describe '.perform_async' do
|
58
58
|
it 'enqueues a message' do
|
59
|
-
expect(sqs_queue).to receive(:send_message).with(
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
59
|
+
expect(sqs_queue).to receive(:send_message).with({
|
60
|
+
message_attributes: {
|
61
|
+
'shoryuken_class' => {
|
62
|
+
string_value: TestWorker.to_s,
|
63
|
+
data_type: 'String'
|
64
|
+
}
|
65
|
+
},
|
66
|
+
message_body: 'message'
|
67
|
+
})
|
68
68
|
|
69
69
|
TestWorker.perform_async('message')
|
70
70
|
end
|
71
71
|
|
72
72
|
it 'enqueues a message with options' do
|
73
|
-
expect(sqs_queue).to receive(:send_message).with(
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
73
|
+
expect(sqs_queue).to receive(:send_message).with({
|
74
|
+
delay_seconds: 60,
|
75
|
+
message_attributes: {
|
76
|
+
'shoryuken_class' => {
|
77
|
+
string_value: TestWorker.to_s,
|
78
|
+
data_type: 'String'
|
79
|
+
}
|
80
|
+
},
|
81
|
+
message_body: 'delayed message'
|
82
|
+
})
|
83
83
|
|
84
84
|
TestWorker.perform_async('delayed message', delay_seconds: 60)
|
85
85
|
end
|
@@ -89,15 +89,15 @@ RSpec.describe Shoryuken::Worker::DefaultExecutor do
|
|
89
89
|
|
90
90
|
expect(Shoryuken::Client).to receive(:queues).with(new_queue).and_return(sqs_queue)
|
91
91
|
|
92
|
-
expect(sqs_queue).to receive(:send_message).with(
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
92
|
+
expect(sqs_queue).to receive(:send_message).with({
|
93
|
+
message_attributes: {
|
94
|
+
'shoryuken_class' => {
|
95
|
+
string_value: TestWorker.to_s,
|
96
|
+
data_type: 'String'
|
97
|
+
}
|
98
|
+
},
|
99
|
+
message_body: 'delayed message'
|
100
|
+
})
|
101
101
|
|
102
102
|
TestWorker.perform_async('delayed message', queue: new_queue)
|
103
103
|
end
|
data/spec/shoryuken_spec.rb
CHANGED
@@ -1,4 +1,13 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
RSpec.describe Shoryuken do
|
4
|
+
describe '.healthy?' do
|
5
|
+
before do
|
6
|
+
allow(Shoryuken::Runner).to receive(:instance).and_return(double(:instance, healthy?: :some_result))
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'delegates to the runner instance' do
|
10
|
+
expect(described_class.healthy?).to eq(:some_result)
|
11
|
+
end
|
12
|
+
end
|
4
13
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
Bundler.setup
|
3
3
|
|
4
|
-
|
4
|
+
begin
|
5
|
+
require 'pry-byebug'
|
6
|
+
rescue LoadError
|
7
|
+
end
|
8
|
+
|
5
9
|
require 'shoryuken'
|
6
10
|
require 'json'
|
7
11
|
require 'dotenv'
|
@@ -28,13 +32,6 @@ class TestWorker
|
|
28
32
|
end
|
29
33
|
|
30
34
|
RSpec.configure do |config|
|
31
|
-
# Only run slow tests if SPEC_ALL=true and AWS_ACCESS_KEY_ID is present
|
32
|
-
# The AWS_ACCESS_KEY_ID checker is because Travis CI
|
33
|
-
# does not expose ENV variables to pull requests from forked repositories
|
34
|
-
# http://docs.travis-ci.com/user/pull-requests/
|
35
|
-
# config.filter_run_excluding slow: true if ENV['SPEC_ALL'] != 'true' || ENV['AWS_ACCESS_KEY_ID'].nil?
|
36
|
-
config.filter_run_excluding slow: true
|
37
|
-
|
38
35
|
config.before do
|
39
36
|
Shoryuken::Client.class_variable_set :@@queues, {}
|
40
37
|
|
@@ -49,6 +46,8 @@ RSpec.configure do |config|
|
|
49
46
|
Shoryuken.options[:logfile] = nil
|
50
47
|
Shoryuken.options[:queues] = nil
|
51
48
|
|
49
|
+
Shoryuken.options[:exception_handlers] = []
|
50
|
+
|
52
51
|
TestWorker.get_shoryuken_options.clear
|
53
52
|
TestWorker.get_shoryuken_options['queue'] = 'default'
|
54
53
|
|
@@ -63,7 +62,6 @@ RSpec.configure do |config|
|
|
63
62
|
|
64
63
|
Shoryuken.cache_visibility_timeout = false
|
65
64
|
|
66
|
-
allow(Concurrent).to receive(:global_io_executor).and_return(Concurrent::ImmediateExecutor.new)
|
67
65
|
allow(Shoryuken).to receive(:active_job?).and_return(false)
|
68
66
|
end
|
69
67
|
end
|