shoryuken 3.1.8 → 3.2.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/.rubocop.yml +1 -1
- data/.travis.yml +12 -2
- data/CHANGELOG.md +34 -0
- data/Gemfile +5 -3
- data/Gemfile.aws-sdk-core-v2 +13 -0
- data/bin/shoryuken +1 -0
- data/lib/shoryuken/body_parser.rb +27 -0
- data/lib/shoryuken/fetcher.rb +27 -6
- data/lib/shoryuken/manager.rb +5 -2
- data/lib/shoryuken/middleware/chain.rb +4 -0
- data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +2 -5
- data/lib/shoryuken/middleware/server/timing.rb +12 -14
- data/lib/shoryuken/options.rb +9 -0
- data/lib/shoryuken/processor.rb +5 -21
- data/lib/shoryuken/util.rb +2 -2
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker/default_executor.rb +33 -0
- data/lib/shoryuken/worker/inline_executor.rb +28 -0
- data/lib/shoryuken/worker.rb +68 -31
- data/lib/shoryuken.rb +11 -0
- data/shoryuken.gemspec +1 -1
- data/spec/shoryuken/body_parser_spec.rb +89 -0
- data/spec/shoryuken/fetcher_spec.rb +16 -0
- data/spec/shoryuken/manager_spec.rb +2 -2
- data/spec/shoryuken/middleware/chain_spec.rb +16 -4
- data/spec/shoryuken/processor_spec.rb +15 -97
- data/spec/shoryuken/util_spec.rb +25 -1
- data/spec/shoryuken/worker/default_executor_spec.rb +100 -0
- data/spec/shoryuken/worker/inline_executor_spec.rb +23 -0
- data/spec/shoryuken/worker_spec.rb +32 -91
- metadata +15 -5
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'shoryuken/body_parser'
|
|
3
|
+
|
|
4
|
+
RSpec.describe Shoryuken::BodyParser do
|
|
5
|
+
let(:sqs_msg) { double }
|
|
6
|
+
|
|
7
|
+
describe '#parser' do
|
|
8
|
+
it 'parses the body into JSON' do
|
|
9
|
+
TestWorker.get_shoryuken_options['body_parser'] = :json
|
|
10
|
+
|
|
11
|
+
body = { 'test' => 'hi' }
|
|
12
|
+
|
|
13
|
+
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
14
|
+
|
|
15
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq(body)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
it 'parses the body calling the proc' do
|
|
19
|
+
TestWorker.get_shoryuken_options['body_parser'] = proc { |sqs_msg| "*#{sqs_msg.body}*" }
|
|
20
|
+
|
|
21
|
+
allow(sqs_msg).to receive(:body).and_return('test')
|
|
22
|
+
|
|
23
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq('*test*')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'parses the body as text' do
|
|
27
|
+
TestWorker.get_shoryuken_options['body_parser'] = :text
|
|
28
|
+
|
|
29
|
+
body = 'test'
|
|
30
|
+
|
|
31
|
+
allow(sqs_msg).to receive(:body).and_return(body)
|
|
32
|
+
|
|
33
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq('test')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'parses calling `.load`' do
|
|
37
|
+
TestWorker.get_shoryuken_options['body_parser'] = Class.new do
|
|
38
|
+
def self.load(*args)
|
|
39
|
+
JSON.load(*args)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
body = { 'test' => 'hi' }
|
|
44
|
+
|
|
45
|
+
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
46
|
+
|
|
47
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq(body)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
it 'parses calling `.parse`' do
|
|
51
|
+
TestWorker.get_shoryuken_options['body_parser'] = Class.new do
|
|
52
|
+
def self.parse(*args)
|
|
53
|
+
JSON.parse(*args)
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
body = { 'test' => 'hi' }
|
|
58
|
+
|
|
59
|
+
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
60
|
+
|
|
61
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq(body)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
context 'when parse errors' do
|
|
65
|
+
before do
|
|
66
|
+
TestWorker.get_shoryuken_options['body_parser'] = :json
|
|
67
|
+
|
|
68
|
+
allow(sqs_msg).to receive(:body).and_return('invalid JSON')
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
specify do
|
|
72
|
+
expect { described_class.parse(TestWorker, sqs_msg) }.
|
|
73
|
+
to raise_error(JSON::ParserError, /unexpected token at 'invalid JSON'/)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
context 'when `object_type: nil`' do
|
|
78
|
+
it 'parses the body as text' do
|
|
79
|
+
TestWorker.get_shoryuken_options['body_parser'] = nil
|
|
80
|
+
|
|
81
|
+
body = 'test'
|
|
82
|
+
|
|
83
|
+
allow(sqs_msg).to receive(:body).and_return(body)
|
|
84
|
+
|
|
85
|
+
expect(described_class.parse(TestWorker, sqs_msg)).to eq(body)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -38,6 +38,22 @@ RSpec.describe Shoryuken::Fetcher do
|
|
|
38
38
|
subject.fetch(queue_config, limit)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
it 'logs debug only' do
|
|
42
|
+
# See https://github.com/phstc/shoryuken/issues/435
|
|
43
|
+
logger = double 'logger'
|
|
44
|
+
|
|
45
|
+
allow(subject).to receive(:logger).and_return(logger)
|
|
46
|
+
|
|
47
|
+
expect(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
|
48
|
+
|
|
49
|
+
expect(queue).to receive(:receive_messages).and_return([double('SQS Msg')])
|
|
50
|
+
|
|
51
|
+
expect(logger).to receive(:debug).exactly(3).times
|
|
52
|
+
expect(logger).to_not receive(:info)
|
|
53
|
+
|
|
54
|
+
subject.fetch(queue_config, limit)
|
|
55
|
+
end
|
|
56
|
+
|
|
41
57
|
context 'when receive options per queue' do
|
|
42
58
|
let(:limit) { 5 }
|
|
43
59
|
|
|
@@ -70,7 +70,7 @@ RSpec.describe Shoryuken::Manager do
|
|
|
70
70
|
q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
|
|
71
71
|
|
|
72
72
|
expect(fetcher).to receive(:fetch).with(q, concurrency).and_return(messages)
|
|
73
|
-
expect(subject).to receive(:fire_event).with(:dispatch)
|
|
73
|
+
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
74
74
|
expect(Shoryuken::Processor).to receive(:process).with(q, message)
|
|
75
75
|
expect(Shoryuken.logger).to_not receive(:info)
|
|
76
76
|
|
|
@@ -83,7 +83,7 @@ RSpec.describe Shoryuken::Manager do
|
|
|
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)
|
|
86
|
-
expect(subject).to receive(:fire_event).with(:dispatch)
|
|
86
|
+
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
87
87
|
allow(subject).to receive(:batched_queue?).with(q).and_return(true)
|
|
88
88
|
expect(Shoryuken::Processor).to receive(:process).with(q, messages)
|
|
89
89
|
expect(Shoryuken.logger).to_not receive(:info)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
describe Shoryuken::Middleware::Chain do
|
|
3
|
+
RSpec.describe Shoryuken::Middleware::Chain do
|
|
4
4
|
class CustomMiddleware
|
|
5
5
|
def initialize(name, recorder)
|
|
6
6
|
@name = name
|
|
@@ -14,20 +14,32 @@ describe Shoryuken::Middleware::Chain do
|
|
|
14
14
|
end
|
|
15
15
|
end
|
|
16
16
|
|
|
17
|
+
class CustomMiddlewareB < CustomMiddleware; end
|
|
18
|
+
|
|
17
19
|
it 'supports custom middleware' do
|
|
18
20
|
subject.add CustomMiddleware, 1, []
|
|
19
21
|
|
|
20
22
|
expect(CustomMiddleware).to eq subject.entries.last.klass
|
|
21
23
|
end
|
|
22
24
|
|
|
25
|
+
it 'can add middleware to the front of chain' do
|
|
26
|
+
subject.prepend CustomMiddleware, 1, []
|
|
27
|
+
|
|
28
|
+
expect([CustomMiddleware]).to eq subject.entries.map(&:klass)
|
|
29
|
+
|
|
30
|
+
subject.prepend CustomMiddlewareB, 1, []
|
|
31
|
+
|
|
32
|
+
expect([CustomMiddlewareB, CustomMiddleware]).to eq subject.entries.map(&:klass)
|
|
33
|
+
end
|
|
34
|
+
|
|
23
35
|
it 'invokes a middleware' do
|
|
24
36
|
recorder = []
|
|
25
|
-
subject.add CustomMiddleware, '
|
|
37
|
+
subject.add CustomMiddleware, 'custom', recorder
|
|
26
38
|
|
|
27
39
|
final_action = nil
|
|
28
40
|
subject.invoke { final_action = true }
|
|
29
41
|
expect(final_action).to eq true
|
|
30
|
-
expect(recorder).to eq [%w
|
|
42
|
+
expect(recorder).to eq [%w(custom before), %w(custom after)]
|
|
31
43
|
end
|
|
32
44
|
|
|
33
45
|
class NonYieldingMiddleware
|
|
@@ -37,7 +49,7 @@ describe Shoryuken::Middleware::Chain do
|
|
|
37
49
|
it 'allows middleware to abruptly stop processing rest of chain' do
|
|
38
50
|
recorder = []
|
|
39
51
|
subject.add NonYieldingMiddleware
|
|
40
|
-
subject.add CustomMiddleware, '
|
|
52
|
+
subject.add CustomMiddleware, 'custom', recorder
|
|
41
53
|
|
|
42
54
|
final_action = nil
|
|
43
55
|
subject.invoke { final_action = true }
|
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
|
-
require 'shoryuken/processor'
|
|
3
|
-
require 'shoryuken/manager'
|
|
4
2
|
|
|
5
3
|
RSpec.describe Shoryuken::Processor do
|
|
6
4
|
let(:manager) { double Shoryuken::Manager }
|
|
@@ -8,12 +6,14 @@ RSpec.describe Shoryuken::Processor do
|
|
|
8
6
|
let(:queue) { 'default' }
|
|
9
7
|
|
|
10
8
|
let(:sqs_msg) do
|
|
11
|
-
double
|
|
9
|
+
double(
|
|
10
|
+
Shoryuken::Message,
|
|
12
11
|
queue_url: queue,
|
|
13
12
|
body: 'test',
|
|
14
13
|
message_attributes: {},
|
|
15
14
|
message_id: SecureRandom.uuid,
|
|
16
15
|
receipt_handle: SecureRandom.uuid
|
|
16
|
+
)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
before do
|
|
@@ -25,101 +25,15 @@ RSpec.describe Shoryuken::Processor do
|
|
|
25
25
|
subject { described_class.new(queue, sqs_msg) }
|
|
26
26
|
|
|
27
27
|
describe '#process' do
|
|
28
|
-
it '
|
|
29
|
-
|
|
28
|
+
it 'sets log context' do
|
|
29
|
+
expect(Shoryuken::Logging).to receive(:with_context).with("TestWorker/#{queue}/#{sqs_msg.message_id}")
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, body)
|
|
34
|
-
|
|
35
|
-
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
31
|
+
allow_any_instance_of(TestWorker).to receive(:perform)
|
|
32
|
+
allow(sqs_msg).to receive(:body)
|
|
36
33
|
|
|
37
34
|
subject.process
|
|
38
35
|
end
|
|
39
36
|
|
|
40
|
-
it 'parses the body calling the proc' do
|
|
41
|
-
TestWorker.get_shoryuken_options['body_parser'] = proc { |sqs_msg| "*#{sqs_msg.body}*" }
|
|
42
|
-
|
|
43
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, '*test*')
|
|
44
|
-
|
|
45
|
-
allow(sqs_msg).to receive(:body).and_return('test')
|
|
46
|
-
|
|
47
|
-
subject.process
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it 'parses the body as text' do
|
|
51
|
-
TestWorker.get_shoryuken_options['body_parser'] = :text
|
|
52
|
-
|
|
53
|
-
body = 'test'
|
|
54
|
-
|
|
55
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, body)
|
|
56
|
-
|
|
57
|
-
allow(sqs_msg).to receive(:body).and_return(body)
|
|
58
|
-
|
|
59
|
-
subject.process
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
it 'parses calling `.load`' do
|
|
63
|
-
TestWorker.get_shoryuken_options['body_parser'] = Class.new do
|
|
64
|
-
def self.load(*args)
|
|
65
|
-
JSON.load(*args)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
body = { 'test' => 'hi' }
|
|
70
|
-
|
|
71
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, body)
|
|
72
|
-
|
|
73
|
-
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
74
|
-
|
|
75
|
-
subject.process
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
it 'parses calling `.parse`' do
|
|
79
|
-
TestWorker.get_shoryuken_options['body_parser'] = Class.new do
|
|
80
|
-
def self.parse(*args)
|
|
81
|
-
JSON.parse(*args)
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
body = { 'test' => 'hi' }
|
|
86
|
-
|
|
87
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, body)
|
|
88
|
-
|
|
89
|
-
allow(sqs_msg).to receive(:body).and_return(JSON.dump(body))
|
|
90
|
-
|
|
91
|
-
subject.process
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
context 'when parse errors' do
|
|
95
|
-
before do
|
|
96
|
-
TestWorker.get_shoryuken_options['body_parser'] = :json
|
|
97
|
-
|
|
98
|
-
allow(sqs_msg).to receive(:body).and_return('invalid JSON')
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
specify do
|
|
102
|
-
expect(subject.logger).to receive(:error).twice
|
|
103
|
-
|
|
104
|
-
expect { subject.process }.
|
|
105
|
-
to raise_error(JSON::ParserError, /unexpected token at 'invalid JSON'/)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
context 'when `object_type: nil`' do
|
|
110
|
-
it 'parses the body as text' do
|
|
111
|
-
TestWorker.get_shoryuken_options['body_parser'] = nil
|
|
112
|
-
|
|
113
|
-
body = 'test'
|
|
114
|
-
|
|
115
|
-
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, body)
|
|
116
|
-
|
|
117
|
-
allow(sqs_msg).to receive(:body).and_return(body)
|
|
118
|
-
|
|
119
|
-
subject.process
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
|
|
123
37
|
context 'when custom middleware' do
|
|
124
38
|
let(:queue) { 'worker_called_middleware' }
|
|
125
39
|
|
|
@@ -220,15 +134,19 @@ RSpec.describe Shoryuken::Processor do
|
|
|
220
134
|
|
|
221
135
|
context 'when shoryuken_class header' do
|
|
222
136
|
let(:sqs_msg) do
|
|
223
|
-
double
|
|
137
|
+
double(
|
|
138
|
+
Shoryuken::Message,
|
|
224
139
|
queue_url: queue,
|
|
225
140
|
body: 'test',
|
|
226
141
|
message_attributes: {
|
|
227
142
|
'shoryuken_class' => {
|
|
228
143
|
string_value: TestWorker.to_s,
|
|
229
|
-
data_type: 'String'
|
|
230
|
-
|
|
231
|
-
|
|
144
|
+
data_type: 'String'
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
message_id: SecureRandom.uuid,
|
|
148
|
+
receipt_handle: SecureRandom.uuid
|
|
149
|
+
)
|
|
232
150
|
end
|
|
233
151
|
|
|
234
152
|
it 'performs without delete' do
|
data/spec/shoryuken/util_spec.rb
CHANGED
|
@@ -9,7 +9,7 @@ describe 'Shoryuken::Util' do
|
|
|
9
9
|
|
|
10
10
|
describe '#unparse_queues' do
|
|
11
11
|
it 'returns queues and weights' do
|
|
12
|
-
queues = %w
|
|
12
|
+
queues = %w(queue1 queue1 queue2 queue3 queue4 queue4 queue4)
|
|
13
13
|
|
|
14
14
|
expect(subject.unparse_queues(queues)).to eq([['queue1', 2], ['queue2', 1], ['queue3', 1], ['queue4', 3]])
|
|
15
15
|
end
|
|
@@ -26,4 +26,28 @@ describe 'Shoryuken::Util' do
|
|
|
26
26
|
|
|
27
27
|
it 'returns ActiveJob worker name'
|
|
28
28
|
end
|
|
29
|
+
|
|
30
|
+
describe '#fire_event' do
|
|
31
|
+
let(:value_holder) { Object.new }
|
|
32
|
+
let(:callback_without_options) { proc { value_holder.value = :without_options } }
|
|
33
|
+
let(:callback_with_options) { proc { |options| value_holder.value = [:with_options, options] } }
|
|
34
|
+
|
|
35
|
+
after :all do
|
|
36
|
+
Shoryuken.options[:lifecycle_events].delete(:some_event)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
it 'triggers callbacks that do not accept arguments' do
|
|
40
|
+
Shoryuken.options[:lifecycle_events][:some_event] = [callback_without_options]
|
|
41
|
+
|
|
42
|
+
expect(value_holder).to receive(:value=).with(:without_options)
|
|
43
|
+
subject.fire_event(:some_event)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
it 'triggers callbacks that accept an argument' do
|
|
47
|
+
Shoryuken.options[:lifecycle_events][:some_event] = [callback_with_options]
|
|
48
|
+
|
|
49
|
+
expect(value_holder).to receive(:value=).with([:with_options, { my_option: :some_option }])
|
|
50
|
+
subject.fire_event(:some_event, false, my_option: :some_option)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
29
53
|
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Shoryuken::Worker::DefaultExecutor do
|
|
4
|
+
let(:sqs_queue) { double 'SQS Queue' }
|
|
5
|
+
let(:queue) { 'default' }
|
|
6
|
+
|
|
7
|
+
before do
|
|
8
|
+
allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe '.perform_in' do
|
|
12
|
+
it 'delays a message' do
|
|
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
|
+
TestWorker.perform_in(60, 'message')
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'raises an exception' do
|
|
27
|
+
expect {
|
|
28
|
+
TestWorker.perform_in(901, 'message')
|
|
29
|
+
}.to raise_error 'The maximum allowed delay is 15 minutes'
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
describe '.perform_at' do
|
|
34
|
+
it 'delays a message' do
|
|
35
|
+
expect(sqs_queue).to receive(:send_message).with(
|
|
36
|
+
message_attributes: {
|
|
37
|
+
'shoryuken_class' => {
|
|
38
|
+
string_value: TestWorker.to_s,
|
|
39
|
+
data_type: 'String'
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
message_body: 'message',
|
|
43
|
+
delay_seconds: 60)
|
|
44
|
+
|
|
45
|
+
TestWorker.perform_in(Time.now + 60, 'message')
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
it 'raises an exception' do
|
|
49
|
+
expect {
|
|
50
|
+
TestWorker.perform_in(Time.now + 901, 'message')
|
|
51
|
+
}.to raise_error 'The maximum allowed delay is 15 minutes'
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe '.perform_async' do
|
|
56
|
+
it 'enqueues a message' do
|
|
57
|
+
expect(sqs_queue).to receive(:send_message).with(
|
|
58
|
+
message_attributes: {
|
|
59
|
+
'shoryuken_class' => {
|
|
60
|
+
string_value: TestWorker.to_s,
|
|
61
|
+
data_type: 'String'
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
message_body: 'message')
|
|
65
|
+
|
|
66
|
+
TestWorker.perform_async('message')
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it 'enqueues a message with options' do
|
|
70
|
+
expect(sqs_queue).to receive(:send_message).with(
|
|
71
|
+
delay_seconds: 60,
|
|
72
|
+
message_attributes: {
|
|
73
|
+
'shoryuken_class' => {
|
|
74
|
+
string_value: TestWorker.to_s,
|
|
75
|
+
data_type: 'String'
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
message_body: 'delayed message')
|
|
79
|
+
|
|
80
|
+
TestWorker.perform_async('delayed message', delay_seconds: 60)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
it 'accepts an `queue` option' do
|
|
84
|
+
new_queue = 'some_different_queue'
|
|
85
|
+
|
|
86
|
+
expect(Shoryuken::Client).to receive(:queues).with(new_queue).and_return(sqs_queue)
|
|
87
|
+
|
|
88
|
+
expect(sqs_queue).to receive(:send_message).with(
|
|
89
|
+
message_attributes: {
|
|
90
|
+
'shoryuken_class' => {
|
|
91
|
+
string_value: TestWorker.to_s,
|
|
92
|
+
data_type: 'String'
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
message_body: 'delayed message')
|
|
96
|
+
|
|
97
|
+
TestWorker.perform_async('delayed message', queue: new_queue)
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe Shoryuken::Worker::InlineExecutor do
|
|
4
|
+
before do
|
|
5
|
+
Shoryuken.worker_executor = described_class
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
describe '.perform_async' do
|
|
9
|
+
specify do
|
|
10
|
+
expect_any_instance_of(TestWorker).to receive(:perform)
|
|
11
|
+
|
|
12
|
+
TestWorker.perform_async('test')
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
describe '.perform_in' do
|
|
17
|
+
specify do
|
|
18
|
+
expect_any_instance_of(TestWorker).to receive(:perform)
|
|
19
|
+
|
|
20
|
+
TestWorker.perform_in(60, 'test')
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
|
-
RSpec.describe
|
|
3
|
+
RSpec.describe Shoryuken::Worker do
|
|
4
4
|
let(:sqs_queue) { double 'SQS Queue' }
|
|
5
5
|
let(:queue) { 'default' }
|
|
6
6
|
|
|
@@ -8,96 +8,6 @@ RSpec.describe 'Shoryuken::Worker' do
|
|
|
8
8
|
allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
describe '.perform_in' do
|
|
12
|
-
it 'delays a message' do
|
|
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
|
-
TestWorker.perform_in(60, 'message')
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it 'raises an exception' do
|
|
27
|
-
expect {
|
|
28
|
-
TestWorker.perform_in(901, 'message')
|
|
29
|
-
}.to raise_error 'The maximum allowed delay is 15 minutes'
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
describe '.perform_at' do
|
|
34
|
-
it 'delays a message' do
|
|
35
|
-
expect(sqs_queue).to receive(:send_message).with(
|
|
36
|
-
message_attributes: {
|
|
37
|
-
'shoryuken_class' => {
|
|
38
|
-
string_value: TestWorker.to_s,
|
|
39
|
-
data_type: 'String'
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
message_body: 'message',
|
|
43
|
-
delay_seconds: 60)
|
|
44
|
-
|
|
45
|
-
TestWorker.perform_in(Time.now + 60, 'message')
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
it 'raises an exception' do
|
|
49
|
-
expect {
|
|
50
|
-
TestWorker.perform_in(Time.now + 901, 'message')
|
|
51
|
-
}.to raise_error 'The maximum allowed delay is 15 minutes'
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
describe '.perform_async' do
|
|
56
|
-
it 'enqueues a message' do
|
|
57
|
-
expect(sqs_queue).to receive(:send_message).with(
|
|
58
|
-
message_attributes: {
|
|
59
|
-
'shoryuken_class' => {
|
|
60
|
-
string_value: TestWorker.to_s,
|
|
61
|
-
data_type: 'String'
|
|
62
|
-
}
|
|
63
|
-
},
|
|
64
|
-
message_body: 'message')
|
|
65
|
-
|
|
66
|
-
TestWorker.perform_async('message')
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it 'enqueues a message with options' do
|
|
70
|
-
expect(sqs_queue).to receive(:send_message).with(
|
|
71
|
-
delay_seconds: 60,
|
|
72
|
-
message_attributes: {
|
|
73
|
-
'shoryuken_class' => {
|
|
74
|
-
string_value: TestWorker.to_s,
|
|
75
|
-
data_type: 'String'
|
|
76
|
-
}
|
|
77
|
-
},
|
|
78
|
-
message_body: 'delayed message')
|
|
79
|
-
|
|
80
|
-
TestWorker.perform_async('delayed message', delay_seconds: 60)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
it 'accepts an `queue` option' do
|
|
84
|
-
new_queue = 'some_different_queue'
|
|
85
|
-
|
|
86
|
-
expect(Shoryuken::Client).to receive(:queues).with(new_queue).and_return(sqs_queue)
|
|
87
|
-
|
|
88
|
-
expect(sqs_queue).to receive(:send_message).with(
|
|
89
|
-
message_attributes: {
|
|
90
|
-
'shoryuken_class' => {
|
|
91
|
-
string_value: TestWorker.to_s,
|
|
92
|
-
data_type: 'String'
|
|
93
|
-
}
|
|
94
|
-
},
|
|
95
|
-
message_body: 'delayed message')
|
|
96
|
-
|
|
97
|
-
TestWorker.perform_async('delayed message', queue: new_queue)
|
|
98
|
-
end
|
|
99
|
-
end
|
|
100
|
-
|
|
101
11
|
describe '.shoryuken_options' do
|
|
102
12
|
it 'registers a worker' do
|
|
103
13
|
expect(Shoryuken.worker_registry.workers('default')).to eq([TestWorker])
|
|
@@ -116,6 +26,20 @@ RSpec.describe 'Shoryuken::Worker' do
|
|
|
116
26
|
expect(NewTestWorker.get_shoryuken_options['queue']).to eq 'production_default'
|
|
117
27
|
end
|
|
118
28
|
|
|
29
|
+
it 'does not change the original hash' do
|
|
30
|
+
class TestWorker
|
|
31
|
+
include Shoryuken::Worker
|
|
32
|
+
|
|
33
|
+
OPT = { queue: :default }
|
|
34
|
+
|
|
35
|
+
shoryuken_options OPT
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
expect(TestWorker::OPT['queue']).to eq(nil)
|
|
39
|
+
expect(TestWorker.get_shoryuken_options['queue']).to eq('default')
|
|
40
|
+
expect(TestWorker::OPT[:queue]).to eq(:default)
|
|
41
|
+
end
|
|
42
|
+
|
|
119
43
|
it 'accepts an array as a queue' do
|
|
120
44
|
class WorkerMultipleQueues
|
|
121
45
|
include Shoryuken::Worker
|
|
@@ -164,6 +88,23 @@ RSpec.describe 'Shoryuken::Worker' do
|
|
|
164
88
|
expect(Shoryuken.worker_registry.workers('symbol_queue2')).to eq([WorkerMultipleSymbolQueues])
|
|
165
89
|
expect(Shoryuken.worker_registry.workers('symbol_queue3')).to eq([WorkerMultipleSymbolQueues])
|
|
166
90
|
end
|
|
91
|
+
|
|
92
|
+
it 'preserves parent class options' do
|
|
93
|
+
class ParentWorker
|
|
94
|
+
include Shoryuken::Worker
|
|
95
|
+
|
|
96
|
+
shoryuken_options queue: "myqueue", auto_delete: false
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class ChildWorker < ParentWorker
|
|
100
|
+
shoryuken_options auto_delete: true
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
expect(ParentWorker.get_shoryuken_options['queue']).to eq("myqueue")
|
|
104
|
+
expect(ChildWorker.get_shoryuken_options['queue']).to eq("myqueue")
|
|
105
|
+
expect(ParentWorker.get_shoryuken_options['auto_delete']).to eq(false)
|
|
106
|
+
expect(ChildWorker.get_shoryuken_options['auto_delete']).to eq(true)
|
|
107
|
+
end
|
|
167
108
|
end
|
|
168
109
|
|
|
169
110
|
describe '.server_middleware' do
|