shoryuken 0.0.5 → 1.0.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/.gitignore +1 -0
- data/.hound.yml +2 -0
- data/.travis.yml +2 -1
- data/Gemfile +2 -0
- data/README.md +20 -8
- data/Rakefile +2 -2
- data/examples/bootstrap_queues.rb +17 -9
- data/lib/shoryuken.rb +27 -3
- data/lib/shoryuken/cli.rb +18 -126
- data/lib/shoryuken/client.rb +26 -12
- data/lib/shoryuken/environment_loader.rb +167 -0
- data/lib/shoryuken/extensions/active_job_adapter.rb +12 -4
- data/lib/shoryuken/fetcher.rb +6 -7
- data/lib/shoryuken/manager.rb +6 -2
- data/lib/shoryuken/middleware/server/auto_delete.rb +7 -1
- data/lib/shoryuken/middleware/server/timing.rb +2 -2
- data/lib/shoryuken/processor.rb +6 -4
- data/lib/shoryuken/sns_arn.rb +27 -0
- data/lib/shoryuken/topic.rb +17 -0
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +4 -9
- data/shoryuken.gemspec +4 -1
- data/spec/integration/launcher_spec.rb +53 -62
- data/spec/shoryuken/client_spec.rb +9 -50
- data/spec/shoryuken/default_worker_registry_spec.rb +1 -1
- data/spec/shoryuken/fetcher_spec.rb +27 -21
- data/spec/shoryuken/middleware/server/auto_delete_spec.rb +20 -8
- data/spec/shoryuken/middleware/server/timing_spec.rb +14 -4
- data/spec/shoryuken/processor_spec.rb +74 -24
- data/spec/shoryuken/sns_arn_spec.rb +42 -0
- data/spec/shoryuken/topic_spec.rb +32 -0
- data/spec/shoryuken/util_spec.rb +3 -1
- data/spec/shoryuken/worker_spec.rb +25 -12
- data/spec/spec_helper.rb +22 -11
- metadata +57 -5
@@ -0,0 +1,167 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class EnvironmentLoader
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def self.load(options)
|
6
|
+
new(options).load
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.load_for_rails_console
|
10
|
+
load(config_file: (Rails.root + 'config' + 'shoryuken.yml'))
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize options
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
def load
|
18
|
+
initialize_logger
|
19
|
+
load_rails if options[:rails]
|
20
|
+
Shoryuken.options.merge!(config_file_options)
|
21
|
+
merge_cli_defined_queues
|
22
|
+
Shoryuken.options.merge!(options)
|
23
|
+
parse_queues
|
24
|
+
require_workers
|
25
|
+
initialize_aws
|
26
|
+
validate_queues
|
27
|
+
validate_workers
|
28
|
+
patch_deprecated_workers
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def config_file_options
|
34
|
+
if (path = options[:config_file])
|
35
|
+
unless File.exist?(path)
|
36
|
+
Shoryuken.logger.warn "Config file #{path} does not exist"
|
37
|
+
path = nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
return {} unless path
|
42
|
+
|
43
|
+
YAML.load(ERB.new(IO.read(path)).result).deep_symbolize_keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def initialize_aws
|
47
|
+
# aws-sdk tries to load the credentials from the ENV variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
|
48
|
+
# when not explicit supplied
|
49
|
+
return if Shoryuken.options[:aws].empty?
|
50
|
+
|
51
|
+
shoryuken_keys = %i(
|
52
|
+
account_id
|
53
|
+
sns_endpoint
|
54
|
+
sqs_endpoint
|
55
|
+
receive_message)
|
56
|
+
|
57
|
+
aws_options = Shoryuken.options[:aws].reject do |k, v|
|
58
|
+
shoryuken_keys.include?(k)
|
59
|
+
end
|
60
|
+
|
61
|
+
credentials = Aws::Credentials.new(
|
62
|
+
aws_options.delete(:access_key_id),
|
63
|
+
aws_options.delete(:secret_access_key))
|
64
|
+
|
65
|
+
aws_options = aws_options.merge(credentials: credentials)
|
66
|
+
|
67
|
+
if callback = Shoryuken.aws_initialization_callback
|
68
|
+
Shoryuken.logger.info "Calling Shoryuken.on_aws_initialization block"
|
69
|
+
callback.call(aws_options)
|
70
|
+
end
|
71
|
+
|
72
|
+
Aws.config = aws_options
|
73
|
+
end
|
74
|
+
|
75
|
+
def initialize_logger
|
76
|
+
Shoryuken::Logging.initialize_logger(options[:logfile]) if options[:logfile]
|
77
|
+
Shoryuken.logger.level = Logger::DEBUG if options[:verbose]
|
78
|
+
end
|
79
|
+
|
80
|
+
def load_rails
|
81
|
+
# Adapted from: https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/cli.rb
|
82
|
+
|
83
|
+
require 'rails'
|
84
|
+
if ::Rails::VERSION::MAJOR < 4
|
85
|
+
require File.expand_path("config/environment.rb")
|
86
|
+
::Rails.application.eager_load!
|
87
|
+
else
|
88
|
+
# Painful contortions, see 1791 for discussion
|
89
|
+
require File.expand_path("config/application.rb")
|
90
|
+
::Rails::Application.initializer "shoryuken.eager_load" do
|
91
|
+
::Rails.application.config.eager_load = true
|
92
|
+
end
|
93
|
+
require 'shoryuken/extensions/active_job_adapter' if defined?(::ActiveJob)
|
94
|
+
require File.expand_path("config/environment.rb")
|
95
|
+
end
|
96
|
+
|
97
|
+
Shoryuken.logger.info "Rails environment loaded"
|
98
|
+
end
|
99
|
+
|
100
|
+
def merge_cli_defined_queues
|
101
|
+
cli_defined_queues = options.delete(:queues) || []
|
102
|
+
|
103
|
+
cli_defined_queues.each do |cli_defined_queue|
|
104
|
+
Shoryuken.options[:queues].delete_if do |config_file_queue|
|
105
|
+
config_file_queue[0] == cli_defined_queue[0]
|
106
|
+
end
|
107
|
+
|
108
|
+
Shoryuken.options[:queues] << cli_defined_queue
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def parse_queue(queue, weight = nil)
|
113
|
+
[weight.to_i, 1].max.times { Shoryuken.queues << queue }
|
114
|
+
end
|
115
|
+
|
116
|
+
def parse_queues
|
117
|
+
Shoryuken.options[:queues].to_a.each do |queue_and_weight|
|
118
|
+
parse_queue(*queue_and_weight)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def patch_deprecated_workers
|
123
|
+
Shoryuken.worker_registry.queues.each do |queue|
|
124
|
+
Shoryuken.worker_registry.workers(queue).each do |worker_class|
|
125
|
+
if worker_class.instance_method(:perform).arity == 1
|
126
|
+
Shoryuken.logger.warn "[DEPRECATION] #{worker_class.name}#perform(sqs_msg) is deprecated. Please use #{worker_class.name}#perform(sqs_msg, body)"
|
127
|
+
|
128
|
+
worker_class.class_eval do
|
129
|
+
alias_method :deprecated_perform, :perform
|
130
|
+
|
131
|
+
def perform(sqs_msg, body = nil)
|
132
|
+
deprecated_perform(sqs_msg)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def require_workers
|
141
|
+
require Shoryuken.options[:require] if Shoryuken.options[:require]
|
142
|
+
end
|
143
|
+
|
144
|
+
def validate_queues
|
145
|
+
Shoryuken.logger.warn 'No queues supplied' if Shoryuken.queues.empty?
|
146
|
+
|
147
|
+
Shoryuken.queues.uniq.each do |queue|
|
148
|
+
begin
|
149
|
+
Shoryuken::Client.queues queue
|
150
|
+
rescue Aws::SQS::Errors::NonExistentQueue
|
151
|
+
Shoryuken.logger.warn "AWS Queue '#{queue}' does not exist"
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
def validate_workers
|
157
|
+
all_queues = Shoryuken.queues
|
158
|
+
queues_with_workers = Shoryuken.worker_registry.queues
|
159
|
+
|
160
|
+
unless defined?(::ActiveJob)
|
161
|
+
(all_queues - queues_with_workers).each do |queue|
|
162
|
+
Shoryuken.logger.warn "No worker supplied for '#{queue}'"
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -19,7 +19,8 @@ module ActiveJob
|
|
19
19
|
def enqueue(job) #:nodoc:
|
20
20
|
register_worker!(job)
|
21
21
|
|
22
|
-
Shoryuken::Client.
|
22
|
+
queue = Shoryuken::Client.queues(job.queue_name)
|
23
|
+
queue.send_message(message(job))
|
23
24
|
end
|
24
25
|
|
25
26
|
def enqueue_at(job, timestamp) #:nodoc:
|
@@ -28,13 +29,20 @@ module ActiveJob
|
|
28
29
|
delay = (timestamp - Time.current.to_f).round
|
29
30
|
raise 'The maximum allowed delay is 15 minutes' if delay > 15.minutes
|
30
31
|
|
31
|
-
Shoryuken::Client.
|
32
|
-
|
32
|
+
queue = Shoryuken::Client.queues(job.queue_name)
|
33
|
+
queue.send_message(message(job, delay_seconds: delay))
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
36
|
private
|
37
37
|
|
38
|
+
def message(job, options = {})
|
39
|
+
body = job.serialize
|
40
|
+
body = JSON.dump(body) if body.is_a?(Hash)
|
41
|
+
|
42
|
+
{ message_body: body,
|
43
|
+
message_attributes: message_attributes }.merge(options)
|
44
|
+
end
|
45
|
+
|
38
46
|
def register_worker!(job)
|
39
47
|
Shoryuken.register_worker(job.queue_name, JobWrapper)
|
40
48
|
end
|
data/lib/shoryuken/fetcher.rb
CHANGED
@@ -9,16 +9,15 @@ module Shoryuken
|
|
9
9
|
@manager = manager
|
10
10
|
end
|
11
11
|
|
12
|
-
def
|
12
|
+
def receive_messages(queue, limit)
|
13
13
|
# AWS limits the batch size by 10
|
14
14
|
limit = limit > FETCH_LIMIT ? FETCH_LIMIT : limit
|
15
15
|
|
16
16
|
options = Shoryuken.options[:aws][:receive_message].to_h.dup
|
17
|
-
options[:
|
18
|
-
options[:message_attribute_names]
|
19
|
-
options[:message_attribute_names] << 'shoryuken_class'
|
17
|
+
options[:max_number_of_messages] = limit
|
18
|
+
options[:message_attribute_names] = %w(All)
|
20
19
|
|
21
|
-
Shoryuken::Client.
|
20
|
+
Shoryuken::Client.queues(queue).receive_messages options
|
22
21
|
end
|
23
22
|
|
24
23
|
def fetch(queue, available_processors)
|
@@ -31,7 +30,7 @@ module Shoryuken
|
|
31
30
|
batch = Shoryuken.worker_registry.batch_receive_messages?(queue)
|
32
31
|
limit = batch ? FETCH_LIMIT : available_processors
|
33
32
|
|
34
|
-
if (sqs_msgs = Array(
|
33
|
+
if (sqs_msgs = Array(receive_messages(queue, limit))).any?
|
35
34
|
logger.info "Found #{sqs_msgs.size} messages for '#{queue}'"
|
36
35
|
|
37
36
|
if batch
|
@@ -63,7 +62,7 @@ module Shoryuken
|
|
63
62
|
|
64
63
|
def patch_sqs_msgs!(sqs_msgs)
|
65
64
|
sqs_msgs.instance_eval do
|
66
|
-
def
|
65
|
+
def message_id
|
67
66
|
"batch-with-#{size}-messages"
|
68
67
|
end
|
69
68
|
end
|
data/lib/shoryuken/manager.rb
CHANGED
@@ -32,6 +32,11 @@ module Shoryuken
|
|
32
32
|
watchdog('Manager#stop died') do
|
33
33
|
@done = true
|
34
34
|
|
35
|
+
if callback = Shoryuken.stop_callback
|
36
|
+
logger.info "Calling Shoryuken.on_stop block"
|
37
|
+
callback.call
|
38
|
+
end
|
39
|
+
|
35
40
|
@fetcher.terminate if @fetcher.alive?
|
36
41
|
|
37
42
|
logger.info { "Shutting down #{@ready.size} quiet workers" }
|
@@ -85,7 +90,7 @@ module Shoryuken
|
|
85
90
|
|
86
91
|
def assign(queue, sqs_msg)
|
87
92
|
watchdog("Manager#assign died") do
|
88
|
-
logger.info "Assigning #{sqs_msg.
|
93
|
+
logger.info "Assigning #{sqs_msg.message_id}"
|
89
94
|
|
90
95
|
processor = @ready.pop
|
91
96
|
@busy << processor
|
@@ -187,7 +192,6 @@ module Shoryuken
|
|
187
192
|
|
188
193
|
unless defined?(::ActiveJob) || !Shoryuken.worker_registry.workers(queue).empty?
|
189
194
|
# when no worker registered pause the queue to avoid endless recursion
|
190
|
-
|
191
195
|
logger.debug "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because no workers registered"
|
192
196
|
|
193
197
|
after(Shoryuken.options[:delay].to_f) { async.restart_queue!(queue) }
|
@@ -7,7 +7,13 @@ module Shoryuken
|
|
7
7
|
|
8
8
|
auto_delete = worker.class.get_shoryuken_options['delete'] || worker.class.get_shoryuken_options['auto_delete']
|
9
9
|
|
10
|
-
|
10
|
+
if auto_delete
|
11
|
+
entries = [sqs_msg].flatten.map.with_index do |message, i|
|
12
|
+
{ id: i.to_s, receipt_handle: message.receipt_handle }
|
13
|
+
end
|
14
|
+
|
15
|
+
Shoryuken::Client.queues(queue).delete_messages(entries: entries)
|
16
|
+
end
|
11
17
|
end
|
12
18
|
end
|
13
19
|
end
|
@@ -5,7 +5,7 @@ module Shoryuken
|
|
5
5
|
include Util
|
6
6
|
|
7
7
|
def call(worker, queue, sqs_msg, body)
|
8
|
-
Shoryuken::Logging.with_context("#{worker_name(worker.class, sqs_msg, body)}/#{queue}/#{sqs_msg.
|
8
|
+
Shoryuken::Logging.with_context("#{worker_name(worker.class, sqs_msg, body)}/#{queue}/#{sqs_msg.message_id}") do
|
9
9
|
begin
|
10
10
|
started_at = Time.now
|
11
11
|
|
@@ -15,7 +15,7 @@ module Shoryuken
|
|
15
15
|
|
16
16
|
total_time = elapsed(started_at)
|
17
17
|
|
18
|
-
if (total_time / 1000.0) > (timeout = Shoryuken::Client.
|
18
|
+
if (total_time / 1000.0) > (timeout = Shoryuken::Client.queues(queue).visibility_timeout)
|
19
19
|
logger.warn "exceeded the queue visibility timeout by #{total_time - (timeout * 1000)} ms"
|
20
20
|
end
|
21
21
|
|
data/lib/shoryuken/processor.rb
CHANGED
@@ -37,13 +37,15 @@ module Shoryuken
|
|
37
37
|
|
38
38
|
def auto_visibility_timeout(queue, sqs_msg, worker_class)
|
39
39
|
if worker_class.auto_visibility_timeout?
|
40
|
-
|
40
|
+
queue_visibility_timeout = Shoryuken::Client.queues(queue).visibility_timeout
|
41
|
+
|
42
|
+
timer = every(queue_visibility_timeout - 5) do
|
41
43
|
begin
|
42
|
-
logger.debug "Extending message #{worker_name(worker_class, sqs_msg)}/#{queue}/#{sqs_msg.
|
44
|
+
logger.debug "Extending message #{worker_name(worker_class, sqs_msg)}/#{queue}/#{sqs_msg.message_id} visibility timeout by #{queue_visibility_timeout}s."
|
43
45
|
|
44
|
-
sqs_msg.visibility_timeout =
|
46
|
+
sqs_msg.visibility_timeout = queue_visibility_timeout
|
45
47
|
rescue => e
|
46
|
-
logger.error "Could not auto extend the message #{worker_class}/#{queue}/#{sqs_msg.
|
48
|
+
logger.error "Could not auto extend the message #{worker_class}/#{queue}/#{sqs_msg.message_id} visibility timeout. Error: #{e.message}"
|
47
49
|
end
|
48
50
|
end
|
49
51
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class SnsArn
|
3
|
+
def initialize topic
|
4
|
+
@topic = topic
|
5
|
+
end
|
6
|
+
|
7
|
+
def to_s
|
8
|
+
@arn ||= "arn:aws:sns:#{region}:#{account_id}:#{@topic}"
|
9
|
+
end
|
10
|
+
|
11
|
+
private
|
12
|
+
|
13
|
+
def account_id
|
14
|
+
Shoryuken::Client.account_id.tap do |account_id|
|
15
|
+
if account_id.to_s.empty?
|
16
|
+
fail "To generate SNS ARNs, you must assign an :account_id in your Shoryuken::Client."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def region
|
22
|
+
Aws.config.fetch(:region) do
|
23
|
+
fail "To generate SNS ARNs, you must include a :region in your AWS config."
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class Topic
|
3
|
+
def initialize(name, sns)
|
4
|
+
@name, @sns = name, sns
|
5
|
+
end
|
6
|
+
|
7
|
+
def arn
|
8
|
+
@arn ||= Client.sns_arn.new(@name).to_s
|
9
|
+
end
|
10
|
+
|
11
|
+
def send_message(body, options = {})
|
12
|
+
body = JSON.dump(body) if body.is_a?(Hash)
|
13
|
+
|
14
|
+
@sns.publish(topic_arn: arn, message: body)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/shoryuken/version.rb
CHANGED
data/lib/shoryuken/worker.rb
CHANGED
@@ -13,7 +13,10 @@ module Shoryuken
|
|
13
13
|
data_type: 'String'
|
14
14
|
}
|
15
15
|
|
16
|
-
|
16
|
+
body = JSON.dump(body) if body.is_a?(Hash)
|
17
|
+
options[:message_body] = body
|
18
|
+
|
19
|
+
Shoryuken::Client.queues(get_shoryuken_options['queue']).send_message(options)
|
17
20
|
end
|
18
21
|
|
19
22
|
def perform_in(interval, body, options = {})
|
@@ -51,14 +54,6 @@ module Shoryuken
|
|
51
54
|
!!get_shoryuken_options['auto_visibility_timeout']
|
52
55
|
end
|
53
56
|
|
54
|
-
def visibility_timeout_heartbeat
|
55
|
-
extended_visibility_timeout - 5
|
56
|
-
end
|
57
|
-
|
58
|
-
def extended_visibility_timeout
|
59
|
-
Shoryuken::Client.visibility_timeout(get_shoryuken_options['queue'])
|
60
|
-
end
|
61
|
-
|
62
57
|
def get_shoryuken_options # :nodoc:
|
63
58
|
@shoryuken_options || Shoryuken.default_worker_options
|
64
59
|
end
|
data/shoryuken.gemspec
CHANGED
@@ -21,7 +21,10 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "rake"
|
22
22
|
spec.add_development_dependency "rspec"
|
23
23
|
spec.add_development_dependency "pry-byebug"
|
24
|
+
spec.add_development_dependency "nokogiri"
|
25
|
+
spec.add_development_dependency "dotenv"
|
24
26
|
|
25
|
-
spec.add_dependency "aws-sdk-
|
27
|
+
spec.add_dependency "aws-sdk-core", "2.0.21"
|
28
|
+
spec.add_dependency "aws-sdk-resources", "2.0.21.pre"
|
26
29
|
spec.add_dependency "celluloid", "~> 0.16.0"
|
27
30
|
end
|
@@ -5,83 +5,41 @@ require 'shoryuken/launcher'
|
|
5
5
|
describe Shoryuken::Launcher do
|
6
6
|
describe 'Consuming messages', slow: :true do
|
7
7
|
before do
|
8
|
-
Shoryuken.options[:aws]
|
9
|
-
Shoryuken.options[:aws][:receive_message] ||= {}
|
10
|
-
Shoryuken.options[:aws][:receive_message][:wait_time_seconds] = 5
|
11
|
-
|
12
|
-
Shoryuken.queues << 'shoryuken'
|
13
|
-
Shoryuken.queues << 'shoryuken_command'
|
14
|
-
|
15
|
-
Shoryuken.register_worker 'shoryuken', StandardWorker
|
16
|
-
Shoryuken.register_worker 'shoryuken_command', CommandWorker
|
17
|
-
|
18
|
-
subject.run
|
8
|
+
Shoryuken.options[:aws][:receive_message] = { wait_time_seconds: 5 }
|
19
9
|
|
20
10
|
StandardWorker.received_messages = 0
|
21
|
-
end
|
22
|
-
|
23
|
-
after { subject.stop }
|
24
|
-
|
25
|
-
class CommandWorker
|
26
|
-
include Shoryuken::Worker
|
27
11
|
|
28
|
-
|
12
|
+
queue = "test_shoryuken#{StandardWorker}_#{SecureRandom.uuid}"
|
29
13
|
|
30
|
-
|
14
|
+
Shoryuken::Client.sqs.create_queue queue_name: queue
|
31
15
|
|
32
|
-
|
33
|
-
@@received_messages = Array(sqs_msg).size
|
34
|
-
end
|
16
|
+
Shoryuken.queues << queue
|
35
17
|
|
36
|
-
|
37
|
-
@@received_messages
|
38
|
-
end
|
18
|
+
StandardWorker.get_shoryuken_options['queue'] = queue
|
39
19
|
|
40
|
-
|
41
|
-
@@received_messages = received_messages
|
42
|
-
end
|
20
|
+
Shoryuken.register_worker queue, StandardWorker
|
43
21
|
end
|
44
22
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
@@received_messages = 0
|
49
|
-
|
50
|
-
shoryuken_options queue: 'shoryuken', auto_delete: true
|
23
|
+
after do
|
24
|
+
queue_url = Shoryuken::Client.sqs.get_queue_url(queue_name: StandardWorker.get_shoryuken_options['queue']).queue_url
|
51
25
|
|
52
|
-
|
53
|
-
@@received_messages = Array(sqs_msg).size
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.received_messages
|
57
|
-
@@received_messages
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.received_messages=(received_messages)
|
61
|
-
@@received_messages = received_messages
|
62
|
-
end
|
26
|
+
Shoryuken::Client.sqs.delete_queue queue_url: queue_url
|
63
27
|
end
|
64
28
|
|
65
29
|
it 'consumes as a command worker' do
|
66
|
-
|
30
|
+
StandardWorker.perform_async('Yo')
|
67
31
|
|
68
|
-
|
69
|
-
break if CommandWorker.received_messages > 0
|
70
|
-
sleep 1
|
71
|
-
end
|
32
|
+
poll_queues_until { StandardWorker.received_messages > 0 }
|
72
33
|
|
73
|
-
expect(
|
34
|
+
expect(StandardWorker.received_messages).to eq 1
|
74
35
|
end
|
75
36
|
|
76
37
|
it 'consumes a message' do
|
77
38
|
StandardWorker.get_shoryuken_options['batch'] = false
|
78
39
|
|
79
|
-
Shoryuken::Client.queues('
|
40
|
+
Shoryuken::Client.queues(StandardWorker.get_shoryuken_options['queue']).send_message(message_body: 'Yo')
|
80
41
|
|
81
|
-
|
82
|
-
break if StandardWorker.received_messages > 0
|
83
|
-
sleep 1
|
84
|
-
end
|
42
|
+
poll_queues_until { StandardWorker.received_messages > 0 }
|
85
43
|
|
86
44
|
expect(StandardWorker.received_messages).to eq 1
|
87
45
|
end
|
@@ -89,15 +47,48 @@ describe Shoryuken::Launcher do
|
|
89
47
|
it 'consumes a batch' do
|
90
48
|
StandardWorker.get_shoryuken_options['batch'] = true
|
91
49
|
|
92
|
-
|
50
|
+
entries = 10.times.map { |i| { id: SecureRandom.uuid, message_body: i.to_s } }
|
93
51
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
52
|
+
Shoryuken::Client.queues(StandardWorker.get_shoryuken_options['queue']).send_messages(entries: entries)
|
53
|
+
|
54
|
+
# Give the messages a chance to hit the queue so they are all available at the same time
|
55
|
+
sleep 2
|
56
|
+
|
57
|
+
poll_queues_until { StandardWorker.received_messages > 0 }
|
98
58
|
|
99
|
-
# the fetch result is uncertain, should be greater than 1, but hard to tell the exact size
|
100
59
|
expect(StandardWorker.received_messages).to be > 1
|
101
60
|
end
|
61
|
+
|
62
|
+
def poll_queues_until
|
63
|
+
subject.run
|
64
|
+
|
65
|
+
Timeout::timeout(10) do
|
66
|
+
begin
|
67
|
+
sleep 0.5
|
68
|
+
end until yield
|
69
|
+
end
|
70
|
+
ensure
|
71
|
+
subject.stop
|
72
|
+
end
|
73
|
+
|
74
|
+
class StandardWorker
|
75
|
+
include Shoryuken::Worker
|
76
|
+
|
77
|
+
@@received_messages = 0
|
78
|
+
|
79
|
+
shoryuken_options auto_delete: true
|
80
|
+
|
81
|
+
def perform(sqs_msg, body)
|
82
|
+
@@received_messages += Array(sqs_msg).size
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.received_messages
|
86
|
+
@@received_messages
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.received_messages=(received_messages)
|
90
|
+
@@received_messages = received_messages
|
91
|
+
end
|
92
|
+
end
|
102
93
|
end
|
103
94
|
end
|