shoryuken 1.0.2 → 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +4 -1
- data/README.md +9 -2
- data/lib/shoryuken.rb +24 -6
- data/lib/shoryuken/cli.rb +9 -9
- data/lib/shoryuken/environment_loader.rb +25 -9
- data/lib/shoryuken/fetcher.rb +6 -6
- data/lib/shoryuken/launcher.rb +1 -1
- data/lib/shoryuken/manager.rb +9 -9
- data/lib/shoryuken/middleware/chain.rb +1 -1
- data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +1 -1
- data/lib/shoryuken/middleware/server/timing.rb +4 -4
- data/lib/shoryuken/processor.rb +27 -13
- data/lib/shoryuken/queue.rb +42 -11
- data/lib/shoryuken/util.rb +4 -4
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +1 -1
- data/spec/shoryuken/middleware/chain_spec.rb +3 -1
- data/spec/shoryuken/middleware/server/timing_spec.rb +21 -7
- data/spec/shoryuken/processor_spec.rb +24 -2
- data/spec/shoryuken/queue_spec.rb +58 -0
- data/spec/spec_helper.rb +4 -1
- metadata +26 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cbdf9963098403163b107d51bab8dc70384b9d92
|
4
|
+
data.tar.gz: 97ccedcd84c67dda49c66f96a21899ee5a2ce215
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a323f68eff71aa37fe470239fbcd1c67210200dc999d0d1e34f4b61e68c4da38f745613cf294d0b238708980e555875afa66d713c3ea2649468a39177dc96437
|
7
|
+
data.tar.gz: 8f7f72e1b4377614e9f7a01c5917b8e0601d59bb8e7669ee2258c7ca8b0adbeeae8f8ea2e5b5130122dcb4b546c671e4f95e295d2dd8bb697cfc0a1fa8a99ff5
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -114,7 +114,7 @@ aws:
|
|
114
114
|
access_key_id: ... # or <%= ENV['AWS_ACCESS_KEY_ID'] %>
|
115
115
|
secret_access_key: ... # or <%= ENV['AWS_SECRET_ACCESS_KEY'] %>
|
116
116
|
region: us-east-1 # or <%= ENV['AWS_REGION'] %>
|
117
|
-
receive_message: # See http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/
|
117
|
+
receive_message: # See http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#receive_message-instance_method
|
118
118
|
# wait_time_seconds: N # The number of seconds to wait for new messages when polling. Defaults to the #wait_time_seconds defined on the queue
|
119
119
|
attribute_names:
|
120
120
|
- ApproximateReceiveCount
|
@@ -132,7 +132,7 @@ The ```aws``` section is used to configure both the Aws objects used by Shoryuke
|
|
132
132
|
- ```account_id``` is used when generating SNS ARNs
|
133
133
|
- ```sns_endpoint``` can be used to explicitly override the SNS endpoint
|
134
134
|
- ```sqs_endpoint``` can be used to explicitly override the SQS endpoint
|
135
|
-
- ```receive_message``` can be used to define the options passed to the http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/
|
135
|
+
- ```receive_message``` can be used to define the options passed to the http://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#receive_message-instance_method
|
136
136
|
|
137
137
|
### Rails Integration
|
138
138
|
|
@@ -186,6 +186,13 @@ See [ActiveJob docs](http://edgeguides.rubyonrails.org/active_job_basics.html) f
|
|
186
186
|
|
187
187
|
*Note:* When queueing jobs to be performed in the future (e.g when setting the `wait` or `wait_until` ActiveJob options), SQS limits the amount of time to 15 minutes. Shoryuken will raise an exception if you attempt to schedule a job further into the future than this limit.
|
188
188
|
|
189
|
+
*Note:* Active Job allows you to [prefix the queue names](http://edgeguides.rubyonrails.org/active_job_basics.html#queues) of all jobs. Shoryuken supports this behavior natively. By default, though, queue names defined in the config file (or passed to the CLI), are not prefixed in the same way. To have Shoryuken honor Active Job prefixes you must enable that option explicitly. A good place to do that in Rails is in an initializer:
|
190
|
+
|
191
|
+
```
|
192
|
+
# config/initializers/shoryuken.rb
|
193
|
+
Shoryuken.active_job_queue_name_prefixing = true
|
194
|
+
```
|
195
|
+
|
189
196
|
### Start Shoryuken
|
190
197
|
|
191
198
|
```shell
|
data/lib/shoryuken.rb
CHANGED
@@ -29,8 +29,9 @@ module Shoryuken
|
|
29
29
|
timeout: 8
|
30
30
|
}
|
31
31
|
|
32
|
-
@@queues
|
32
|
+
@@queues = []
|
33
33
|
@@worker_registry = DefaultWorkerRegistry.new
|
34
|
+
@@active_job_queue_name_prefixing = false
|
34
35
|
|
35
36
|
class << self
|
36
37
|
def options
|
@@ -57,11 +58,14 @@ module Shoryuken
|
|
57
58
|
@@worker_registry
|
58
59
|
end
|
59
60
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
def active_job_queue_name_prefixing
|
62
|
+
@@active_job_queue_name_prefixing
|
63
|
+
end
|
64
|
+
|
65
|
+
def active_job_queue_name_prefixing=(prefixing)
|
66
|
+
@@active_job_queue_name_prefixing = prefixing
|
67
|
+
end
|
68
|
+
|
65
69
|
def configure_server
|
66
70
|
yield self if server?
|
67
71
|
end
|
@@ -72,6 +76,16 @@ module Shoryuken
|
|
72
76
|
@server_chain
|
73
77
|
end
|
74
78
|
|
79
|
+
def configure_client
|
80
|
+
yield self
|
81
|
+
end
|
82
|
+
|
83
|
+
def client_middleware
|
84
|
+
@client_chain ||= default_client_middleware
|
85
|
+
yield @client_chain if block_given?
|
86
|
+
@client_chain
|
87
|
+
end
|
88
|
+
|
75
89
|
def default_worker_options
|
76
90
|
@@default_worker_options ||= {
|
77
91
|
'queue' => 'default',
|
@@ -116,6 +130,10 @@ module Shoryuken
|
|
116
130
|
end
|
117
131
|
end
|
118
132
|
|
133
|
+
def default_client_middleware
|
134
|
+
Middleware::Chain.new
|
135
|
+
end
|
136
|
+
|
119
137
|
def server?
|
120
138
|
defined?(Shoryuken::CLI)
|
121
139
|
end
|
data/lib/shoryuken/cli.rb
CHANGED
@@ -41,7 +41,7 @@ module Shoryuken
|
|
41
41
|
@launcher = Shoryuken::Launcher.new
|
42
42
|
|
43
43
|
if callback = Shoryuken.start_callback
|
44
|
-
logger.info
|
44
|
+
logger.info { 'Calling Shoryuken.on_start block' }
|
45
45
|
callback.call
|
46
46
|
end
|
47
47
|
|
@@ -158,7 +158,7 @@ module Shoryuken
|
|
158
158
|
|
159
159
|
@parser.banner = 'shoryuken [options]'
|
160
160
|
@parser.on_tail '-h', '--help', 'Show help' do
|
161
|
-
logger.info @parser
|
161
|
+
logger.info { @parser }
|
162
162
|
exit 1
|
163
163
|
end
|
164
164
|
@parser.parse!(argv)
|
@@ -166,22 +166,22 @@ module Shoryuken
|
|
166
166
|
end
|
167
167
|
|
168
168
|
def handle_signal(sig)
|
169
|
-
logger.info "Got #{sig} signal"
|
169
|
+
logger.info { "Got #{sig} signal" }
|
170
170
|
|
171
171
|
case sig
|
172
172
|
when 'USR1'
|
173
|
-
logger.info 'Received USR1, will soft shutdown down'
|
173
|
+
logger.info { 'Received USR1, will soft shutdown down' }
|
174
174
|
|
175
175
|
launcher.stop
|
176
176
|
|
177
177
|
exit 0
|
178
178
|
when 'TTIN'
|
179
179
|
Thread.list.each do |thread|
|
180
|
-
logger.info "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}"
|
180
|
+
logger.info { "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}" }
|
181
181
|
if thread.backtrace
|
182
|
-
logger.info thread.backtrace.join("\n")
|
182
|
+
logger.info { thread.backtrace.join("\n") }
|
183
183
|
else
|
184
|
-
logger.info '<no backtrace available>'
|
184
|
+
logger.info { '<no backtrace available>' }
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
@@ -189,9 +189,9 @@ module Shoryuken
|
|
189
189
|
busy = launcher.manager.instance_variable_get(:@busy).size
|
190
190
|
queues = launcher.manager.instance_variable_get(:@queues)
|
191
191
|
|
192
|
-
logger.info "Ready: #{ready}, Busy: #{busy}, Active Queues: #{unparse_queues(queues)}"
|
192
|
+
logger.info { "Ready: #{ready}, Busy: #{busy}, Active Queues: #{unparse_queues(queues)}" }
|
193
193
|
else
|
194
|
-
logger.info "Received #{sig}, will shutdown down"
|
194
|
+
logger.info { "Received #{sig}, will shutdown down" }
|
195
195
|
|
196
196
|
raise Interrupt
|
197
197
|
end
|
@@ -19,6 +19,7 @@ module Shoryuken
|
|
19
19
|
load_rails if options[:rails]
|
20
20
|
Shoryuken.options.merge!(config_file_options)
|
21
21
|
merge_cli_defined_queues
|
22
|
+
prefix_active_job_queue_names
|
22
23
|
Shoryuken.options.merge!(options)
|
23
24
|
parse_queues
|
24
25
|
require_workers
|
@@ -33,7 +34,7 @@ module Shoryuken
|
|
33
34
|
def config_file_options
|
34
35
|
if (path = options[:config_file])
|
35
36
|
unless File.exist?(path)
|
36
|
-
Shoryuken.logger.warn "Config file #{path} does not exist"
|
37
|
+
Shoryuken.logger.warn { "Config file #{path} does not exist" }
|
37
38
|
path = nil
|
38
39
|
end
|
39
40
|
end
|
@@ -48,11 +49,11 @@ module Shoryuken
|
|
48
49
|
# when not explicit supplied
|
49
50
|
return if Shoryuken.options[:aws].empty?
|
50
51
|
|
51
|
-
shoryuken_keys = %
|
52
|
+
shoryuken_keys = %w(
|
52
53
|
account_id
|
53
54
|
sns_endpoint
|
54
55
|
sqs_endpoint
|
55
|
-
receive_message)
|
56
|
+
receive_message).map(&:to_sym)
|
56
57
|
|
57
58
|
aws_options = Shoryuken.options[:aws].reject do |k, v|
|
58
59
|
shoryuken_keys.include?(k)
|
@@ -67,7 +68,7 @@ module Shoryuken
|
|
67
68
|
aws_options = aws_options.merge(credentials: credentials) if credentials.set?
|
68
69
|
|
69
70
|
if (callback = Shoryuken.aws_initialization_callback)
|
70
|
-
Shoryuken.logger.info 'Calling Shoryuken.on_aws_initialization block'
|
71
|
+
Shoryuken.logger.info { 'Calling Shoryuken.on_aws_initialization block' }
|
71
72
|
callback.call(aws_options)
|
72
73
|
end
|
73
74
|
|
@@ -96,7 +97,7 @@ module Shoryuken
|
|
96
97
|
require File.expand_path('config/environment.rb')
|
97
98
|
end
|
98
99
|
|
99
|
-
Shoryuken.logger.info 'Rails environment loaded'
|
100
|
+
Shoryuken.logger.info { 'Rails environment loaded' }
|
100
101
|
end
|
101
102
|
|
102
103
|
def merge_cli_defined_queues
|
@@ -111,6 +112,21 @@ module Shoryuken
|
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
115
|
+
def prefix_active_job_queue_names
|
116
|
+
return unless @options[:rails]
|
117
|
+
return unless Shoryuken.active_job_queue_name_prefixing
|
118
|
+
|
119
|
+
queue_name_prefix = ::ActiveJob::Base.queue_name_prefix
|
120
|
+
queue_name_delimiter = ::ActiveJob::Base.queue_name_delimiter
|
121
|
+
|
122
|
+
# See https://github.com/rails/rails/blob/master/activejob/lib/active_job/queue_name.rb#L27
|
123
|
+
Shoryuken.options[:queues].to_a.map! do |queue_name, weight|
|
124
|
+
name_parts = [queue_name_prefix.presence, queue_name]
|
125
|
+
prefixed_queue_name = name_parts.compact.join(queue_name_delimiter)
|
126
|
+
[prefixed_queue_name, weight]
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
114
130
|
def parse_queue(queue, weight = nil)
|
115
131
|
[weight.to_i, 1].max.times { Shoryuken.queues << queue }
|
116
132
|
end
|
@@ -125,7 +141,7 @@ module Shoryuken
|
|
125
141
|
Shoryuken.worker_registry.queues.each do |queue|
|
126
142
|
Shoryuken.worker_registry.workers(queue).each do |worker_class|
|
127
143
|
if worker_class.instance_method(:perform).arity == 1
|
128
|
-
Shoryuken.logger.warn "[DEPRECATION] #{worker_class.name}#perform(sqs_msg) is deprecated. Please use #{worker_class.name}#perform(sqs_msg, body)"
|
144
|
+
Shoryuken.logger.warn { "[DEPRECATION] #{worker_class.name}#perform(sqs_msg) is deprecated. Please use #{worker_class.name}#perform(sqs_msg, body)" }
|
129
145
|
|
130
146
|
worker_class.class_eval do
|
131
147
|
alias_method :deprecated_perform, :perform
|
@@ -144,13 +160,13 @@ module Shoryuken
|
|
144
160
|
end
|
145
161
|
|
146
162
|
def validate_queues
|
147
|
-
Shoryuken.logger.warn 'No queues supplied' if Shoryuken.queues.empty?
|
163
|
+
Shoryuken.logger.warn { 'No queues supplied' } if Shoryuken.queues.empty?
|
148
164
|
|
149
165
|
Shoryuken.queues.uniq.each do |queue|
|
150
166
|
begin
|
151
167
|
Shoryuken::Client.queues queue
|
152
168
|
rescue Aws::SQS::Errors::NonExistentQueue
|
153
|
-
Shoryuken.logger.warn "AWS Queue '#{queue}' does not exist"
|
169
|
+
Shoryuken.logger.warn { "AWS Queue '#{queue}' does not exist" }
|
154
170
|
end
|
155
171
|
end
|
156
172
|
end
|
@@ -161,7 +177,7 @@ module Shoryuken
|
|
161
177
|
|
162
178
|
unless defined?(::ActiveJob)
|
163
179
|
(all_queues - queues_with_workers).each do |queue|
|
164
|
-
Shoryuken.logger.warn "No worker supplied for '#{queue}'"
|
180
|
+
Shoryuken.logger.warn { "No worker supplied for '#{queue}'" }
|
165
181
|
end
|
166
182
|
end
|
167
183
|
end
|
data/lib/shoryuken/fetcher.rb
CHANGED
@@ -13,7 +13,7 @@ module Shoryuken
|
|
13
13
|
# AWS limits the batch size by 10
|
14
14
|
limit = limit > FETCH_LIMIT ? FETCH_LIMIT : limit
|
15
15
|
|
16
|
-
options = Shoryuken.options[:aws][:receive_message].
|
16
|
+
options = (Shoryuken.options[:aws][:receive_message] || {}).dup
|
17
17
|
options[:max_number_of_messages] = limit
|
18
18
|
options[:message_attribute_names] = %w(All)
|
19
19
|
options[:attribute_names] = %w(All)
|
@@ -25,14 +25,14 @@ module Shoryuken
|
|
25
25
|
watchdog('Fetcher#fetch died') do
|
26
26
|
started_at = Time.now
|
27
27
|
|
28
|
-
logger.debug "Looking for new messages in '#{queue}'"
|
28
|
+
logger.debug { "Looking for new messages in '#{queue}'" }
|
29
29
|
|
30
30
|
begin
|
31
31
|
batch = Shoryuken.worker_registry.batch_receive_messages?(queue)
|
32
32
|
limit = batch ? FETCH_LIMIT : available_processors
|
33
33
|
|
34
34
|
if (sqs_msgs = Array(receive_messages(queue, limit))).any?
|
35
|
-
logger.info "Found #{sqs_msgs.size} messages for '#{queue}'"
|
35
|
+
logger.info { "Found #{sqs_msgs.size} messages for '#{queue}'" }
|
36
36
|
|
37
37
|
if batch
|
38
38
|
@manager.async.assign(queue, patch_sqs_msgs!(sqs_msgs))
|
@@ -42,7 +42,7 @@ module Shoryuken
|
|
42
42
|
|
43
43
|
@manager.async.rebalance_queue_weight!(queue)
|
44
44
|
else
|
45
|
-
logger.debug "No message found for '#{queue}'"
|
45
|
+
logger.debug { "No message found for '#{queue}'" }
|
46
46
|
|
47
47
|
@manager.async.pause_queue!(queue)
|
48
48
|
end
|
@@ -51,8 +51,8 @@ module Shoryuken
|
|
51
51
|
|
52
52
|
logger.debug { "Fetcher for '#{queue}' completed in #{elapsed(started_at)} ms" }
|
53
53
|
rescue => ex
|
54
|
-
logger.error "Error fetching message: #{ex}"
|
55
|
-
logger.error ex.backtrace.first
|
54
|
+
logger.error { "Error fetching message: #{ex}" }
|
55
|
+
logger.error { ex.backtrace.first }
|
56
56
|
|
57
57
|
@manager.async.dispatch
|
58
58
|
end
|
data/lib/shoryuken/launcher.rb
CHANGED
@@ -36,7 +36,7 @@ module Shoryuken
|
|
36
36
|
|
37
37
|
def actor_died(actor, reason)
|
38
38
|
return if @done
|
39
|
-
logger.warn 'Shoryuken died due to the following error, cannot recover, process exiting'
|
39
|
+
logger.warn { 'Shoryuken died due to the following error, cannot recover, process exiting' }
|
40
40
|
exit 1
|
41
41
|
end
|
42
42
|
end
|
data/lib/shoryuken/manager.rb
CHANGED
@@ -23,7 +23,7 @@ module Shoryuken
|
|
23
23
|
end
|
24
24
|
|
25
25
|
def start
|
26
|
-
logger.info 'Starting'
|
26
|
+
logger.info { 'Starting' }
|
27
27
|
|
28
28
|
dispatch
|
29
29
|
end
|
@@ -33,7 +33,7 @@ module Shoryuken
|
|
33
33
|
@done = true
|
34
34
|
|
35
35
|
if (callback = Shoryuken.stop_callback)
|
36
|
-
logger.info 'Calling Shoryuken.on_stop block'
|
36
|
+
logger.info { 'Calling Shoryuken.on_stop block' }
|
37
37
|
callback.call
|
38
38
|
end
|
39
39
|
|
@@ -58,7 +58,7 @@ module Shoryuken
|
|
58
58
|
|
59
59
|
def processor_done(queue, processor)
|
60
60
|
watchdog('Manager#processor_done died') do
|
61
|
-
logger.
|
61
|
+
logger.debug { "Process done for '#{queue}'" }
|
62
62
|
|
63
63
|
@threads.delete(processor.object_id)
|
64
64
|
@busy.delete processor
|
@@ -73,7 +73,7 @@ module Shoryuken
|
|
73
73
|
|
74
74
|
def processor_died(processor, reason)
|
75
75
|
watchdog("Manager#processor_died died") do
|
76
|
-
logger.error "Process died, reason: #{reason}" unless reason.to_s.empty?
|
76
|
+
logger.error { "Process died, reason: #{reason}" unless reason.to_s.empty? }
|
77
77
|
|
78
78
|
@threads.delete(processor.object_id)
|
79
79
|
@busy.delete processor
|
@@ -90,7 +90,7 @@ module Shoryuken
|
|
90
90
|
|
91
91
|
def assign(queue, sqs_msg)
|
92
92
|
watchdog('Manager#assign died') do
|
93
|
-
logger.
|
93
|
+
logger.debug { "Assigning #{sqs_msg.message_id}" }
|
94
94
|
|
95
95
|
processor = @ready.pop
|
96
96
|
@busy << processor
|
@@ -102,7 +102,7 @@ module Shoryuken
|
|
102
102
|
def rebalance_queue_weight!(queue)
|
103
103
|
watchdog('Manager#rebalance_queue_weight! died') do
|
104
104
|
if (original = original_queue_weight(queue)) > (current = current_queue_weight(queue))
|
105
|
-
logger.info "Increasing '#{queue}' weight to #{current + 1}, max: #{original}"
|
105
|
+
logger.info { "Increasing '#{queue}' weight to #{current + 1}, max: #{original}" }
|
106
106
|
|
107
107
|
@queues << queue
|
108
108
|
end
|
@@ -112,7 +112,7 @@ module Shoryuken
|
|
112
112
|
def pause_queue!(queue)
|
113
113
|
return if !@queues.include?(queue) || Shoryuken.options[:delay].to_f <= 0
|
114
114
|
|
115
|
-
logger.debug "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because it's empty"
|
115
|
+
logger.debug { "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because it's empty" }
|
116
116
|
|
117
117
|
@queues.delete(queue)
|
118
118
|
|
@@ -158,7 +158,7 @@ module Shoryuken
|
|
158
158
|
return if stopped?
|
159
159
|
|
160
160
|
unless @queues.include? queue
|
161
|
-
logger.debug "Restarting '#{queue}'"
|
161
|
+
logger.debug { "Restarting '#{queue}'" }
|
162
162
|
|
163
163
|
@queues << queue
|
164
164
|
|
@@ -192,7 +192,7 @@ module Shoryuken
|
|
192
192
|
|
193
193
|
unless defined?(::ActiveJob) || !Shoryuken.worker_registry.workers(queue).empty?
|
194
194
|
# when no worker registered pause the queue to avoid endless recursion
|
195
|
-
logger.debug "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because no workers registered"
|
195
|
+
logger.debug { "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because no workers registered" }
|
196
196
|
|
197
197
|
after(Shoryuken.options[:delay].to_f) { async.restart_queue!(queue) }
|
198
198
|
|
@@ -117,7 +117,7 @@ module Shoryuken
|
|
117
117
|
|
118
118
|
def patch_deprecated_middleware!(klass)
|
119
119
|
if klass.instance_method(:call).arity == 3
|
120
|
-
Shoryuken.logger.warn "[DEPRECATION] #{klass.name}#call(worker_instance, queue, sqs_msg) is deprecated. Please use #{klass.name}#call(worker_instance, queue, sqs_msg, body)"
|
120
|
+
Shoryuken.logger.warn { "[DEPRECATION] #{klass.name}#call(worker_instance, queue, sqs_msg) is deprecated. Please use #{klass.name}#call(worker_instance, queue, sqs_msg, body)" }
|
121
121
|
|
122
122
|
klass.class_eval do
|
123
123
|
alias_method :deprecated_call, :call
|
@@ -42,7 +42,7 @@ module Shoryuken
|
|
42
42
|
|
43
43
|
sqs_msg.change_visibility(visibility_timeout: interval.to_i)
|
44
44
|
|
45
|
-
logger.info "Message #{sqs_msg.message_id} failed, will be retried in #{interval} seconds."
|
45
|
+
logger.info { "Message #{sqs_msg.message_id} failed, will be retried in #{interval} seconds." }
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -9,19 +9,19 @@ module Shoryuken
|
|
9
9
|
begin
|
10
10
|
started_at = Time.now
|
11
11
|
|
12
|
-
logger.info "started at #{started_at}"
|
12
|
+
logger.info { "started at #{started_at}" }
|
13
13
|
|
14
14
|
yield
|
15
15
|
|
16
16
|
total_time = elapsed(started_at)
|
17
17
|
|
18
18
|
if (total_time / 1000.0) > (timeout = Shoryuken::Client.queues(queue).visibility_timeout)
|
19
|
-
logger.warn "exceeded the queue visibility timeout by #{total_time - (timeout * 1000)} ms"
|
19
|
+
logger.warn { "exceeded the queue visibility timeout by #{total_time - (timeout * 1000)} ms" }
|
20
20
|
end
|
21
21
|
|
22
|
-
logger.info "completed in: #{total_time} ms"
|
22
|
+
logger.info { "completed in: #{total_time} ms" }
|
23
23
|
rescue => e
|
24
|
-
logger.info "failed in: #{elapsed(started_at)} ms"
|
24
|
+
logger.info { "failed in: #{elapsed(started_at)} ms" }
|
25
25
|
raise e
|
26
26
|
end
|
27
27
|
end
|
data/lib/shoryuken/processor.rb
CHANGED
@@ -19,12 +19,10 @@ module Shoryuken
|
|
19
19
|
timer = auto_visibility_timeout(queue, sqs_msg, worker.class)
|
20
20
|
|
21
21
|
begin
|
22
|
-
|
23
|
-
body = get_body(worker.class, sqs_msg)
|
22
|
+
body = get_body(worker.class, sqs_msg)
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
end
|
24
|
+
worker.class.server_middleware.invoke(worker, queue, sqs_msg, body) do
|
25
|
+
worker.perform(sqs_msg, body)
|
28
26
|
end
|
29
27
|
|
30
28
|
@manager.async.processor_done(queue, current_actor)
|
@@ -35,22 +33,31 @@ module Shoryuken
|
|
35
33
|
|
36
34
|
private
|
37
35
|
|
38
|
-
|
39
|
-
|
36
|
+
class MessageVisibilityExtender
|
37
|
+
include Celluloid
|
38
|
+
include Util
|
39
|
+
|
40
|
+
def auto_extend(queue, sqs_msg, worker_class)
|
40
41
|
queue_visibility_timeout = Shoryuken::Client.queues(queue).visibility_timeout
|
41
42
|
|
42
|
-
|
43
|
+
every(queue_visibility_timeout - 5) do
|
43
44
|
begin
|
44
|
-
logger.debug "Extending message #{worker_name(worker_class, sqs_msg)}/#{queue}/#{sqs_msg.message_id} visibility timeout by #{queue_visibility_timeout}s."
|
45
|
+
logger.debug { "Extending message #{worker_name(worker_class, sqs_msg)}/#{queue}/#{sqs_msg.message_id} visibility timeout by #{queue_visibility_timeout}s." }
|
45
46
|
|
46
47
|
sqs_msg.visibility_timeout = queue_visibility_timeout
|
47
48
|
rescue => e
|
48
|
-
logger.error "Could not auto extend the message #{worker_class}/#{queue}/#{sqs_msg.message_id} visibility timeout. Error: #{e.message}"
|
49
|
+
logger.error { "Could not auto extend the message #{worker_class}/#{queue}/#{sqs_msg.message_id} visibility timeout. Error: #{e.message}" }
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
53
|
+
end
|
52
54
|
|
53
|
-
|
55
|
+
def auto_visibility_timeout(queue, sqs_msg, worker_class)
|
56
|
+
return unless worker_class.auto_visibility_timeout?
|
57
|
+
|
58
|
+
@visibility_extender ||= MessageVisibilityExtender.new_link
|
59
|
+
|
60
|
+
@visibility_extender.auto_extend(queue, sqs_msg, worker_class)
|
54
61
|
end
|
55
62
|
|
56
63
|
def get_body(worker_class, sqs_msg)
|
@@ -72,10 +79,17 @@ module Shoryuken
|
|
72
79
|
when :text, nil
|
73
80
|
sqs_msg.body
|
74
81
|
else
|
75
|
-
|
82
|
+
if body_parser.respond_to?(:parse)
|
83
|
+
# JSON.parse
|
84
|
+
body_parser.parse(sqs_msg.body)
|
85
|
+
elsif body_parser.respond_to?(:load)
|
86
|
+
# see https://github.com/phstc/shoryuken/pull/91
|
87
|
+
# JSON.load
|
88
|
+
body_parser.load(sqs_msg.body)
|
89
|
+
end
|
76
90
|
end
|
77
91
|
rescue => e
|
78
|
-
logger.error "Error parsing the message body: #{e.message}\nbody_parser: #{body_parser}\nsqs_msg.body: #{sqs_msg.body}"
|
92
|
+
logger.error { "Error parsing the message body: #{e.message}\nbody_parser: #{body_parser}\nsqs_msg.body: #{sqs_msg.body}" }
|
79
93
|
nil
|
80
94
|
end
|
81
95
|
end
|
data/lib/shoryuken/queue.rb
CHANGED
@@ -20,11 +20,15 @@ module Shoryuken
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def send_message(options)
|
23
|
-
|
23
|
+
options = sanitize_message!(options).merge(queue_url: url)
|
24
|
+
|
25
|
+
Shoryuken.client_middleware.invoke(options) do
|
26
|
+
client.send_message(options)
|
27
|
+
end
|
24
28
|
end
|
25
29
|
|
26
30
|
def send_messages(options)
|
27
|
-
client.send_message_batch(
|
31
|
+
client.send_message_batch(sanitize_messages!(options).merge(queue_url: url))
|
28
32
|
end
|
29
33
|
|
30
34
|
def receive_messages(options)
|
@@ -35,16 +39,43 @@ module Shoryuken
|
|
35
39
|
|
36
40
|
private
|
37
41
|
|
38
|
-
def
|
39
|
-
|
42
|
+
def sanitize_messages!(options)
|
43
|
+
options = case
|
44
|
+
when options.is_a?(Array)
|
45
|
+
{ entries: options.map.with_index { |m, index| { id: index.to_s, message_body: m } } }
|
46
|
+
when options.is_a?(Hash)
|
47
|
+
options
|
48
|
+
end
|
49
|
+
|
50
|
+
validate_messages!(options)
|
51
|
+
|
52
|
+
options
|
53
|
+
end
|
54
|
+
|
55
|
+
def sanitize_message!(options)
|
56
|
+
options = case
|
57
|
+
when options.is_a?(String)
|
58
|
+
# send_message('message')
|
59
|
+
{ message_body: options }
|
60
|
+
when options.is_a?(Hash)
|
61
|
+
options
|
62
|
+
end
|
63
|
+
|
64
|
+
validate_message!(options)
|
65
|
+
|
66
|
+
options
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_messages!(options)
|
70
|
+
options[:entries].map { |m| validate_message!(m) }
|
71
|
+
end
|
40
72
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
73
|
+
def validate_message!(options)
|
74
|
+
body = options[:message_body]
|
75
|
+
if body.is_a?(Hash)
|
76
|
+
options[:message_body] = JSON.dump(body)
|
77
|
+
elsif !body.is_a?(String)
|
78
|
+
fail ArgumentError, "The message body must be a String and you passed a #{body.class}"
|
48
79
|
end
|
49
80
|
|
50
81
|
options
|
data/lib/shoryuken/util.rb
CHANGED
@@ -3,9 +3,9 @@ module Shoryuken
|
|
3
3
|
def watchdog(last_words)
|
4
4
|
yield
|
5
5
|
rescue => ex
|
6
|
-
logger.error last_words
|
7
|
-
logger.error ex
|
8
|
-
logger.error ex.backtrace.join("\n")
|
6
|
+
logger.error { last_words }
|
7
|
+
logger.error { ex }
|
8
|
+
logger.error { ex.backtrace.join("\n") }
|
9
9
|
end
|
10
10
|
|
11
11
|
def logger
|
@@ -30,7 +30,7 @@ module Shoryuken
|
|
30
30
|
&& sqs_msg.message_attributes['shoryuken_class'] \
|
31
31
|
&& sqs_msg.message_attributes['shoryuken_class'][:string_value] == ActiveJob::QueueAdapters::ShoryukenAdapter::JobWrapper.to_s
|
32
32
|
|
33
|
-
"ActiveJob/#{body['job_class']
|
33
|
+
"ActiveJob/#{body['job_class']}"
|
34
34
|
else
|
35
35
|
worker_class.to_s
|
36
36
|
end
|
data/lib/shoryuken/version.rb
CHANGED
data/lib/shoryuken/worker.rb
CHANGED
@@ -39,7 +39,7 @@ module Shoryuken
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def shoryuken_options(opts = {})
|
42
|
-
@shoryuken_options = get_shoryuken_options.merge(stringify_keys(
|
42
|
+
@shoryuken_options = get_shoryuken_options.merge(stringify_keys(opts || {}))
|
43
43
|
queue = @shoryuken_options['queue']
|
44
44
|
if queue.respond_to? :call
|
45
45
|
queue = queue.call
|
@@ -58,7 +58,9 @@ describe Shoryuken::Middleware::Chain do
|
|
58
58
|
it 'patches deprecated middleware' do
|
59
59
|
subject.clear
|
60
60
|
|
61
|
-
expect(Shoryuken.logger).to receive(:warn)
|
61
|
+
expect(Shoryuken.logger).to receive(:warn) do |&block|
|
62
|
+
expect(block.call).to eq('[DEPRECATION] DeprecatedMiddleware#call(worker_instance, queue, sqs_msg) is deprecated. Please use DeprecatedMiddleware#call(worker_instance, queue, sqs_msg, body)')
|
63
|
+
end
|
62
64
|
|
63
65
|
subject.add DeprecatedMiddleware
|
64
66
|
|
@@ -16,8 +16,12 @@ describe Shoryuken::Middleware::Server::Timing do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'logs timing' do
|
19
|
-
expect(Shoryuken.logger).to receive(:info)
|
20
|
-
|
19
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
20
|
+
expect(block.call).to match(/started at/)
|
21
|
+
end
|
22
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
23
|
+
expect(block.call).to match(/completed in/)
|
24
|
+
end
|
21
25
|
|
22
26
|
subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
|
23
27
|
end
|
@@ -26,9 +30,15 @@ describe Shoryuken::Middleware::Server::Timing do
|
|
26
30
|
it 'logs exceeded' do
|
27
31
|
allow(subject).to receive(:elapsed).and_return(120000)
|
28
32
|
|
29
|
-
expect(Shoryuken.logger).to receive(:info)
|
30
|
-
|
31
|
-
|
33
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
34
|
+
expect(block.call).to match(/started at/)
|
35
|
+
end
|
36
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
37
|
+
expect(block.call).to match(/completed in/)
|
38
|
+
end
|
39
|
+
expect(Shoryuken.logger).to receive(:warn) do |&block|
|
40
|
+
expect(block.call).to match('exceeded the queue visibility timeout by 60000 ms')
|
41
|
+
end
|
32
42
|
|
33
43
|
subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
|
34
44
|
end
|
@@ -36,8 +46,12 @@ describe Shoryuken::Middleware::Server::Timing do
|
|
36
46
|
|
37
47
|
context 'when exception' do
|
38
48
|
it 'logs failed in' do
|
39
|
-
expect(Shoryuken.logger).to receive(:info)
|
40
|
-
|
49
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
50
|
+
expect(block.call).to match(/started at/)
|
51
|
+
end
|
52
|
+
expect(Shoryuken.logger).to receive(:info) do |&block|
|
53
|
+
expect(block.call).to match(/failed in/)
|
54
|
+
end
|
41
55
|
|
42
56
|
expect {
|
43
57
|
subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise }
|
@@ -59,8 +59,28 @@ describe Shoryuken::Processor do
|
|
59
59
|
subject.process(queue, sqs_msg)
|
60
60
|
end
|
61
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(queue, sqs_msg)
|
76
|
+
end
|
77
|
+
|
62
78
|
it 'parses calling `.parse`' do
|
63
|
-
TestWorker.get_shoryuken_options['body_parser'] =
|
79
|
+
TestWorker.get_shoryuken_options['body_parser'] = Class.new do
|
80
|
+
def self.parse(*args)
|
81
|
+
JSON.parse(*args)
|
82
|
+
end
|
83
|
+
end
|
64
84
|
|
65
85
|
body = { 'test' => 'hi' }
|
66
86
|
|
@@ -79,7 +99,9 @@ describe Shoryuken::Processor do
|
|
79
99
|
|
80
100
|
allow(sqs_msg).to receive(:body).and_return('invalid json')
|
81
101
|
|
82
|
-
expect(subject.logger).to receive(:error)
|
102
|
+
expect(subject.logger).to receive(:error) do |&block|
|
103
|
+
expect(block.call).to eq("Error parsing the message body: 757: unexpected token at 'invalid json'\nbody_parser: json\nsqs_msg.body: invalid json")
|
104
|
+
end
|
83
105
|
|
84
106
|
subject.process(queue, sqs_msg)
|
85
107
|
end
|
@@ -9,6 +9,19 @@ describe Shoryuken::Queue do
|
|
9
9
|
subject { described_class.new(sqs, queue_name) }
|
10
10
|
|
11
11
|
describe '#send_message' do
|
12
|
+
it 'accepts SQS request parameters' do
|
13
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#send_message-instance_method
|
14
|
+
expect(sqs).to receive(:send_message).with(hash_including(message_body: 'msg1'))
|
15
|
+
|
16
|
+
subject.send_message(message_body: 'msg1')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'accepts a string' do
|
20
|
+
expect(sqs).to receive(:send_message).with(hash_including(message_body: 'msg1'))
|
21
|
+
|
22
|
+
subject.send_message('msg1')
|
23
|
+
end
|
24
|
+
|
12
25
|
context 'when body is invalid' do
|
13
26
|
it 'raises ArgumentError for nil' do
|
14
27
|
expect {
|
@@ -21,10 +34,55 @@ describe Shoryuken::Queue do
|
|
21
34
|
subject.send_message(message_body: 1)
|
22
35
|
}.to raise_error(ArgumentError, 'The message body must be a String and you passed a Fixnum')
|
23
36
|
end
|
37
|
+
|
38
|
+
context 'when a client middleware' do
|
39
|
+
class MyClientMiddleware
|
40
|
+
def call(options)
|
41
|
+
options[:message_body] = 'changed'
|
42
|
+
|
43
|
+
yield
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
before do
|
48
|
+
Shoryuken.configure_client do |config|
|
49
|
+
config.client_middleware do |chain|
|
50
|
+
chain.add MyClientMiddleware
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
after do
|
56
|
+
Shoryuken.configure_client do |config|
|
57
|
+
config.client_middleware do |chain|
|
58
|
+
chain.remove MyClientMiddleware
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'invokes MyClientMiddleware' do
|
64
|
+
expect(sqs).to receive(:send_message).with(hash_including(message_body: 'changed'))
|
65
|
+
|
66
|
+
subject.send_message(message_body: 'original')
|
67
|
+
end
|
68
|
+
end
|
24
69
|
end
|
25
70
|
end
|
26
71
|
|
27
72
|
describe '#send_messages' do
|
73
|
+
it 'accepts SQS request parameters' do
|
74
|
+
# https://docs.aws.amazon.com/sdkforruby/api/Aws/SQS/Client.html#send_message_batch-instance_method
|
75
|
+
expect(sqs).to receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1'}, { id: '1', message_body: 'msg2' }]))
|
76
|
+
|
77
|
+
subject.send_messages(entries: [{ id: '0', message_body: 'msg1'}, { id: '1', message_body: 'msg2' }])
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'accepts an array of string' do
|
81
|
+
expect(sqs).to receive(:send_message_batch).with(hash_including(entries: [{ id: '0', message_body: 'msg1'}, { id: '1', message_body: 'msg2' }]))
|
82
|
+
|
83
|
+
subject.send_messages(%w(msg1 msg2))
|
84
|
+
end
|
85
|
+
|
28
86
|
context 'when body is invalid' do
|
29
87
|
it 'raises ArgumentError for nil' do
|
30
88
|
expect {
|
data/spec/spec_helper.rb
CHANGED
@@ -39,7 +39,10 @@ class TestWorker
|
|
39
39
|
end
|
40
40
|
|
41
41
|
RSpec.configure do |config|
|
42
|
-
|
42
|
+
# Only run slow tests if SPEC_ALL=true and AWS_ACCESS_KEY_ID is present
|
43
|
+
# The AWS_ACCESS_KEY_ID checker is because Travis CI does not expose ENV variables to pull requests from forked repositories
|
44
|
+
# http://docs.travis-ci.com/user/pull-requests/
|
45
|
+
config.filter_run_excluding slow: true if ENV['SPEC_ALL'] != 'true' || ENV['AWS_ACCESS_KEY_ID'].nil?
|
43
46
|
|
44
47
|
config.before do
|
45
48
|
Shoryuken::Client.class_variable_set :@@queues, {}
|
metadata
CHANGED
@@ -1,125 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shoryuken
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pablo Cantero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-07-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.6'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.6'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: pry-byebug
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: nokogiri
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: dotenv
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: aws-sdk-core
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - ~>
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
103
|
version: 2.0.21
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - ~>
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: 2.0.21
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: celluloid
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- - ~>
|
115
|
+
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
117
|
version: 0.16.0
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- - ~>
|
122
|
+
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
124
|
version: 0.16.0
|
125
125
|
description: Shoryuken is a super efficient AWS SQS thread based message processor
|
@@ -130,11 +130,11 @@ executables:
|
|
130
130
|
extensions: []
|
131
131
|
extra_rdoc_files: []
|
132
132
|
files:
|
133
|
-
- .gitignore
|
134
|
-
- .hound.yml
|
135
|
-
- .rspec
|
136
|
-
- .rubocop.yml
|
137
|
-
- .travis.yml
|
133
|
+
- ".gitignore"
|
134
|
+
- ".hound.yml"
|
135
|
+
- ".rspec"
|
136
|
+
- ".rubocop.yml"
|
137
|
+
- ".travis.yml"
|
138
138
|
- Gemfile
|
139
139
|
- LICENSE.txt
|
140
140
|
- README.md
|
@@ -198,17 +198,17 @@ require_paths:
|
|
198
198
|
- lib
|
199
199
|
required_ruby_version: !ruby/object:Gem::Requirement
|
200
200
|
requirements:
|
201
|
-
- -
|
201
|
+
- - ">="
|
202
202
|
- !ruby/object:Gem::Version
|
203
203
|
version: '0'
|
204
204
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
205
|
requirements:
|
206
|
-
- -
|
206
|
+
- - ">="
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '0'
|
209
209
|
requirements: []
|
210
210
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.
|
211
|
+
rubygems_version: 2.2.3
|
212
212
|
signing_key:
|
213
213
|
specification_version: 4
|
214
214
|
summary: Shoryuken is a super efficient AWS SQS thread based message processor
|