shoryuken 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.hound.yml +6 -2
- data/.rubocop.yml +50 -0
- data/examples/bootstrap_queues.rb +1 -1
- data/lib/shoryuken.rb +5 -1
- data/lib/shoryuken/cli.rb +7 -7
- data/lib/shoryuken/client.rb +2 -6
- data/lib/shoryuken/default_worker_registry.rb +1 -1
- data/lib/shoryuken/environment_loader.rb +8 -8
- data/lib/shoryuken/extensions/active_job_adapter.rb +0 -1
- data/lib/shoryuken/fetcher.rb +2 -0
- data/lib/shoryuken/logging.rb +4 -6
- data/lib/shoryuken/manager.rb +5 -5
- data/lib/shoryuken/message.rb +60 -0
- data/lib/shoryuken/middleware/chain.rb +1 -1
- data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +50 -0
- data/lib/shoryuken/queue.rb +53 -0
- data/lib/shoryuken/sns_arn.rb +3 -3
- data/lib/shoryuken/util.rb +1 -2
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +0 -1
- data/shoryuken.gemspec +15 -16
- data/spec/shoryuken/default_worker_registry_spec.rb +1 -1
- data/spec/shoryuken/fetcher_spec.rb +6 -6
- data/spec/shoryuken/middleware/server/auto_delete_spec.rb +2 -2
- data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +77 -0
- data/spec/shoryuken/middleware/server/timing_spec.rb +2 -2
- data/spec/shoryuken/processor_spec.rb +7 -7
- data/spec/shoryuken/queue_spec.rb +42 -0
- data/spec/shoryuken/util_spec.rb +1 -1
- data/spec/shoryuken/worker_spec.rb +0 -13
- data/spec/spec_helper.rb +0 -3
- metadata +12 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 08068a4a26c1f914715b25a27e463fac07e31b57
|
4
|
+
data.tar.gz: ac4fc670aac9fb76dec2c8c369f021ace729f0cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fdf1a335919582abb26bd34583de36da01b117b2e952b5d4874d40f4ee28b5d86cdca65fe9d4d52a807347569d2c9cb50bb20e82f8f6801ebf49aa2638219856
|
7
|
+
data.tar.gz: c9d462d292894b91ffe066af240ee5e7c6b8232542f19ba9d849a05bb9d7a0b6b732d6f96dbe6096610bbd9e4857f4540eed53bd5fd60b19c888dc8b88692e6b
|
data/.gitignore
CHANGED
data/.hound.yml
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
LineLength:
|
2
|
+
Max: 120
|
3
|
+
|
4
|
+
Style/SignalException:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Style/SpaceAroundEqualsInParameterDefault:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Style/ClassAndModuleChildren:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Metrics/PerceivedComplexity:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
Metrics/CyclomaticComplexity:
|
20
|
+
Enabled: false
|
21
|
+
|
22
|
+
Style/CommentAnnotation:
|
23
|
+
Enabled: false
|
24
|
+
|
25
|
+
Metrics/ClassLength:
|
26
|
+
Enabled: false
|
27
|
+
|
28
|
+
Metrics/ParameterLists:
|
29
|
+
Enabled: false
|
30
|
+
|
31
|
+
Metrics/MethodLength :
|
32
|
+
Enabled: false
|
33
|
+
|
34
|
+
Style/PerlBackrefs:
|
35
|
+
Enabled: false
|
36
|
+
|
37
|
+
Style/StringLiterals:
|
38
|
+
EnforcedStyle: single_quotes
|
39
|
+
SupportedStyles:
|
40
|
+
- single_quotes
|
41
|
+
- double_quotes
|
42
|
+
|
43
|
+
Style/StringLiteralsInInterpolation:
|
44
|
+
EnforcedStyle: single_quotes
|
45
|
+
SupportedStyles:
|
46
|
+
- single_quotes
|
47
|
+
- double_quotes
|
48
|
+
|
49
|
+
Lint/UnusedMethodArgument:
|
50
|
+
Enabled: false
|
@@ -22,7 +22,7 @@ if sqs.config['endpoint'] =~ /amazonaws.com/
|
|
22
22
|
).attributes['QueueArn']
|
23
23
|
|
24
24
|
attributes = {}
|
25
|
-
attributes['RedrivePolicy'] = %Q{
|
25
|
+
attributes['RedrivePolicy'] = %Q({"maxReceiveCount":"7", "deadLetterTargetArn":"#{dead_letter_queue_arn}"})
|
26
26
|
|
27
27
|
sqs.set_queue_attributes queue_url: default_queue_url, attributes: attributes
|
28
28
|
end
|
data/lib/shoryuken.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'yaml'
|
2
2
|
require 'aws-sdk-core'
|
3
|
-
require 'aws-sdk-resources'
|
4
3
|
require 'time'
|
5
4
|
|
6
5
|
require 'shoryuken/version'
|
@@ -8,12 +7,15 @@ require 'shoryuken/core_ext'
|
|
8
7
|
require 'shoryuken/util'
|
9
8
|
require 'shoryuken/logging'
|
10
9
|
require 'shoryuken/environment_loader'
|
10
|
+
require 'shoryuken/queue'
|
11
|
+
require 'shoryuken/message'
|
11
12
|
require 'shoryuken/client'
|
12
13
|
require 'shoryuken/worker'
|
13
14
|
require 'shoryuken/worker_registry'
|
14
15
|
require 'shoryuken/default_worker_registry'
|
15
16
|
require 'shoryuken/middleware/chain'
|
16
17
|
require 'shoryuken/middleware/server/auto_delete'
|
18
|
+
require 'shoryuken/middleware/server/exponential_backoff_retry'
|
17
19
|
require 'shoryuken/middleware/server/timing'
|
18
20
|
require 'shoryuken/sns_arn'
|
19
21
|
require 'shoryuken/topic'
|
@@ -76,6 +78,7 @@ module Shoryuken
|
|
76
78
|
'delete' => false,
|
77
79
|
'auto_delete' => false,
|
78
80
|
'auto_visibility_timeout' => false,
|
81
|
+
'retry_intervals' => nil,
|
79
82
|
'batch' => false }
|
80
83
|
end
|
81
84
|
|
@@ -104,6 +107,7 @@ module Shoryuken
|
|
104
107
|
def default_server_middleware
|
105
108
|
Middleware::Chain.new do |m|
|
106
109
|
m.add Middleware::Server::Timing
|
110
|
+
m.add Middleware::Server::ExponentialBackoffRetry
|
107
111
|
m.add Middleware::Server::AutoDelete
|
108
112
|
if defined?(::ActiveRecord::Base)
|
109
113
|
require 'shoryuken/middleware/server/active_record'
|
data/lib/shoryuken/cli.rb
CHANGED
@@ -19,7 +19,7 @@ module Shoryuken
|
|
19
19
|
def run(args)
|
20
20
|
self_read, self_write = IO.pipe
|
21
21
|
|
22
|
-
%w
|
22
|
+
%w(INT TERM USR1 USR2 TTIN).each do |sig|
|
23
23
|
begin
|
24
24
|
trap sig do
|
25
25
|
self_write.puts(sig)
|
@@ -48,7 +48,7 @@ module Shoryuken
|
|
48
48
|
begin
|
49
49
|
launcher.run
|
50
50
|
|
51
|
-
while readable_io = IO.select([self_read])
|
51
|
+
while (readable_io = IO.select([self_read]))
|
52
52
|
signal = readable_io.first[0].gets.strip
|
53
53
|
handle_signal(signal)
|
54
54
|
end
|
@@ -86,7 +86,7 @@ module Shoryuken
|
|
86
86
|
|
87
87
|
files_to_reopen.each do |file|
|
88
88
|
begin
|
89
|
-
file.reopen file.path,
|
89
|
+
file.reopen file.path, 'a+'
|
90
90
|
file.sync = true
|
91
91
|
rescue ::Exception
|
92
92
|
end
|
@@ -102,7 +102,7 @@ module Shoryuken
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def write_pid
|
105
|
-
if path = Shoryuken.options[:pidfile]
|
105
|
+
if (path = Shoryuken.options[:pidfile])
|
106
106
|
File.open(path, 'w') do |f|
|
107
107
|
f.puts Process.pid
|
108
108
|
end
|
@@ -150,7 +150,7 @@ module Shoryuken
|
|
150
150
|
opts[:verbose] = arg
|
151
151
|
end
|
152
152
|
|
153
|
-
o.on '-V', '--version', 'Print version and exit' do
|
153
|
+
o.on '-V', '--version', 'Print version and exit' do
|
154
154
|
puts "Shoryuken #{Shoryuken::VERSION}"
|
155
155
|
exit 0
|
156
156
|
end
|
@@ -170,7 +170,7 @@ module Shoryuken
|
|
170
170
|
|
171
171
|
case sig
|
172
172
|
when 'USR1'
|
173
|
-
logger.info
|
173
|
+
logger.info 'Received USR1, will soft shutdown down'
|
174
174
|
|
175
175
|
launcher.stop
|
176
176
|
|
@@ -181,7 +181,7 @@ module Shoryuken
|
|
181
181
|
if thread.backtrace
|
182
182
|
logger.info thread.backtrace.join("\n")
|
183
183
|
else
|
184
|
-
logger.info
|
184
|
+
logger.info '<no backtrace available>'
|
185
185
|
end
|
186
186
|
end
|
187
187
|
|
data/lib/shoryuken/client.rb
CHANGED
@@ -5,7 +5,7 @@ module Shoryuken
|
|
5
5
|
|
6
6
|
class << self
|
7
7
|
def queues(name)
|
8
|
-
@@queues[name.to_s] ||=
|
8
|
+
@@queues[name.to_s] ||= Shoryuken::Queue.new(sqs, name)
|
9
9
|
end
|
10
10
|
|
11
11
|
def sns
|
@@ -20,10 +20,6 @@ module Shoryuken
|
|
20
20
|
@sqs ||= Aws::SQS::Client.new(aws_client_options(:sqs_endpoint))
|
21
21
|
end
|
22
22
|
|
23
|
-
def sqs_resource
|
24
|
-
@sqs_resource ||= Aws::SQS::Resource.new(client: sqs)
|
25
|
-
end
|
26
|
-
|
27
23
|
def topics(name)
|
28
24
|
@@topics[name.to_s] ||= Topic.new(name, sns)
|
29
25
|
end
|
@@ -33,7 +29,7 @@ module Shoryuken
|
|
33
29
|
|
34
30
|
private
|
35
31
|
|
36
|
-
def aws_client_options
|
32
|
+
def aws_client_options(service_endpoint_key)
|
37
33
|
explicit_endpoint = Shoryuken.options[:aws][service_endpoint_key]
|
38
34
|
options = {}
|
39
35
|
options[:endpoint] = explicit_endpoint unless explicit_endpoint.to_s.empty?
|
@@ -28,7 +28,7 @@ module Shoryuken
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def register_worker(queue, clazz)
|
31
|
-
if worker_class = @workers[queue]
|
31
|
+
if (worker_class = @workers[queue])
|
32
32
|
if worker_class.get_shoryuken_options['batch'] == true || clazz.get_shoryuken_options['batch'] == true
|
33
33
|
raise ArgumentError, "Could not register #{clazz} for '#{queue}', "\
|
34
34
|
"because #{worker_class} is already registered for this queue, "\
|
@@ -10,7 +10,7 @@ module Shoryuken
|
|
10
10
|
load(config_file: (Rails.root + 'config' + 'shoryuken.yml'))
|
11
11
|
end
|
12
12
|
|
13
|
-
def initialize
|
13
|
+
def initialize(options)
|
14
14
|
@options = options
|
15
15
|
end
|
16
16
|
|
@@ -64,8 +64,8 @@ module Shoryuken
|
|
64
64
|
|
65
65
|
aws_options = aws_options.merge(credentials: credentials)
|
66
66
|
|
67
|
-
if callback = Shoryuken.aws_initialization_callback
|
68
|
-
Shoryuken.logger.info
|
67
|
+
if (callback = Shoryuken.aws_initialization_callback)
|
68
|
+
Shoryuken.logger.info 'Calling Shoryuken.on_aws_initialization block'
|
69
69
|
callback.call(aws_options)
|
70
70
|
end
|
71
71
|
|
@@ -82,19 +82,19 @@ module Shoryuken
|
|
82
82
|
|
83
83
|
require 'rails'
|
84
84
|
if ::Rails::VERSION::MAJOR < 4
|
85
|
-
require File.expand_path(
|
85
|
+
require File.expand_path('config/environment.rb')
|
86
86
|
::Rails.application.eager_load!
|
87
87
|
else
|
88
88
|
# Painful contortions, see 1791 for discussion
|
89
|
-
require File.expand_path(
|
90
|
-
::Rails::Application.initializer
|
89
|
+
require File.expand_path('config/application.rb')
|
90
|
+
::Rails::Application.initializer 'shoryuken.eager_load' do
|
91
91
|
::Rails.application.config.eager_load = true
|
92
92
|
end
|
93
93
|
require 'shoryuken/extensions/active_job_adapter' if defined?(::ActiveJob)
|
94
|
-
require File.expand_path(
|
94
|
+
require File.expand_path('config/environment.rb')
|
95
95
|
end
|
96
96
|
|
97
|
-
Shoryuken.logger.info
|
97
|
+
Shoryuken.logger.info 'Rails environment loaded'
|
98
98
|
end
|
99
99
|
|
100
100
|
def merge_cli_defined_queues
|
data/lib/shoryuken/fetcher.rb
CHANGED
@@ -16,6 +16,7 @@ module Shoryuken
|
|
16
16
|
options = Shoryuken.options[:aws][:receive_message].to_h.dup
|
17
17
|
options[:max_number_of_messages] = limit
|
18
18
|
options[:message_attribute_names] = %w(All)
|
19
|
+
options[:attribute_names] = %w(All)
|
19
20
|
|
20
21
|
Shoryuken::Client.queues(queue).receive_messages options
|
21
22
|
end
|
@@ -58,6 +59,7 @@ module Shoryuken
|
|
58
59
|
end
|
59
60
|
|
60
61
|
end
|
62
|
+
|
61
63
|
private
|
62
64
|
|
63
65
|
def patch_sqs_msgs!(sqs_msgs)
|
data/lib/shoryuken/logging.rb
CHANGED
@@ -17,12 +17,10 @@ module Shoryuken
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def self.with_context(msg)
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
Thread.current[:shoryuken_context] = nil
|
25
|
-
end
|
20
|
+
Thread.current[:shoryuken_context] = msg
|
21
|
+
yield
|
22
|
+
ensure
|
23
|
+
Thread.current[:shoryuken_context] = nil
|
26
24
|
end
|
27
25
|
|
28
26
|
def self.initialize_logger(log_target = STDOUT)
|
data/lib/shoryuken/manager.rb
CHANGED
@@ -32,8 +32,8 @@ module Shoryuken
|
|
32
32
|
watchdog('Manager#stop died') do
|
33
33
|
@done = true
|
34
34
|
|
35
|
-
if callback = Shoryuken.stop_callback
|
36
|
-
logger.info
|
35
|
+
if (callback = Shoryuken.stop_callback)
|
36
|
+
logger.info 'Calling Shoryuken.on_stop block'
|
37
37
|
callback.call
|
38
38
|
end
|
39
39
|
|
@@ -89,7 +89,7 @@ module Shoryuken
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def assign(queue, sqs_msg)
|
92
|
-
watchdog(
|
92
|
+
watchdog('Manager#assign died') do
|
93
93
|
logger.info "Assigning #{sqs_msg.message_id}"
|
94
94
|
|
95
95
|
processor = @ready.pop
|
@@ -133,7 +133,7 @@ module Shoryuken
|
|
133
133
|
return
|
134
134
|
end
|
135
135
|
|
136
|
-
if queue = next_queue
|
136
|
+
if (queue = next_queue)
|
137
137
|
@fetcher.async.fetch(queue, @ready.size)
|
138
138
|
else
|
139
139
|
logger.debug { 'Pausing fetcher, because all queues are paused' }
|
@@ -220,7 +220,7 @@ module Shoryuken
|
|
220
220
|
logger.info { "Pausing up to #{delay} seconds to allow workers to finish..." }
|
221
221
|
|
222
222
|
after(delay) do
|
223
|
-
watchdog(
|
223
|
+
watchdog('Manager#hard_shutdown_in died') do
|
224
224
|
if @busy.size > 0
|
225
225
|
logger.info { "Hard shutting down #{@busy.size} busy workers" }
|
226
226
|
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class Message
|
3
|
+
attr_accessor :client, :queue_url, :data
|
4
|
+
|
5
|
+
def initialize(client, queue_url, data)
|
6
|
+
self.client = client
|
7
|
+
self.queue_url = queue_url
|
8
|
+
self.data = data
|
9
|
+
end
|
10
|
+
|
11
|
+
def delete
|
12
|
+
client.delete_message(
|
13
|
+
queue_url: queue_url,
|
14
|
+
receipt_handle: data.receipt_handle
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def change_visibility(options)
|
19
|
+
client.change_message_visibility(
|
20
|
+
options.merge(queue_url: queue_url, receipt_handle: data.receipt_handle)
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def visibility_timeout=(timeout)
|
25
|
+
client.change_message_visibility(
|
26
|
+
queue_url: queue_url,
|
27
|
+
receipt_handle: data.receipt_handle,
|
28
|
+
visibility_timeout: timeout
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def message_id
|
33
|
+
data.message_id
|
34
|
+
end
|
35
|
+
|
36
|
+
def receipt_handle
|
37
|
+
data.receipt_handle
|
38
|
+
end
|
39
|
+
|
40
|
+
def md5_of_body
|
41
|
+
data.md5_of_body
|
42
|
+
end
|
43
|
+
|
44
|
+
def body
|
45
|
+
data.body
|
46
|
+
end
|
47
|
+
|
48
|
+
def attributes
|
49
|
+
data.attributes
|
50
|
+
end
|
51
|
+
|
52
|
+
def md5_of_message_attributes
|
53
|
+
data.md5_of_message_attributes
|
54
|
+
end
|
55
|
+
|
56
|
+
def message_attributes
|
57
|
+
data.message_attributes
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -72,7 +72,7 @@ module Shoryuken
|
|
72
72
|
i = entries.index { |entry| entry.klass == newklass }
|
73
73
|
new_entry = i.nil? ? Entry.new(newklass, *args) : entries.delete_at(i)
|
74
74
|
i = entries.find_index { |entry| entry.klass == oldklass } || entries.count - 1
|
75
|
-
entries.insert(i+1, new_entry)
|
75
|
+
entries.insert(i + 1, new_entry)
|
76
76
|
end
|
77
77
|
|
78
78
|
def exists?(klass)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
module Middleware
|
3
|
+
module Server
|
4
|
+
class ExponentialBackoffRetry
|
5
|
+
include Util
|
6
|
+
|
7
|
+
def call(worker, queue, sqs_msg, body)
|
8
|
+
started_at = Time.now
|
9
|
+
yield
|
10
|
+
rescue
|
11
|
+
retry_intervals = Array(worker.class.get_shoryuken_options['retry_intervals'])
|
12
|
+
|
13
|
+
if retry_intervals.empty? || !handle_failure(sqs_msg, started_at, retry_intervals)
|
14
|
+
# Re-raise the exception if the job is not going to be exponential backoff retried.
|
15
|
+
# This allows custom middleware (like exception notifiers) to be aware of the unhandled failure.
|
16
|
+
raise
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def handle_failure(sqs_msg, started_at, retry_intervals)
|
23
|
+
attempts = sqs_msg.attributes['ApproximateReceiveCount']
|
24
|
+
|
25
|
+
return unless attempts
|
26
|
+
|
27
|
+
attempts = attempts.to_i - 1
|
28
|
+
|
29
|
+
interval = if attempts < retry_intervals.size
|
30
|
+
retry_intervals[attempts]
|
31
|
+
else
|
32
|
+
retry_intervals.last
|
33
|
+
end
|
34
|
+
|
35
|
+
# Visibility timeouts are limited to a total 12 hours, starting from the receipt of the message.
|
36
|
+
# We calculate the maximum timeout by subtracting the amount of time since the receipt of the message.
|
37
|
+
#
|
38
|
+
# From the docs: "Amazon SQS restarts the timeout period using the new value."
|
39
|
+
# http://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/AboutVT.html#AboutVT-extending-message-visibility-timeout
|
40
|
+
max_timeout = 43200 - (Time.now - started_at).ceil - 1
|
41
|
+
interval = max_timeout if interval > max_timeout
|
42
|
+
|
43
|
+
sqs_msg.change_visibility(visibility_timeout: interval.to_i)
|
44
|
+
|
45
|
+
logger.info "Message #{sqs_msg.message_id} failed, will be retried in #{interval} seconds."
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class Queue
|
3
|
+
attr_accessor :name, :client, :url
|
4
|
+
|
5
|
+
def initialize(client, name)
|
6
|
+
self.name = name
|
7
|
+
self.client = client
|
8
|
+
self.url = client.get_queue_url(queue_name: name).queue_url
|
9
|
+
end
|
10
|
+
|
11
|
+
def visibility_timeout
|
12
|
+
client.get_queue_attributes(
|
13
|
+
queue_url: url,
|
14
|
+
attribute_names: ['VisibilityTimeout']
|
15
|
+
).attributes['VisibilityTimeout'].to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def delete_messages(options)
|
19
|
+
client.delete_message_batch(options.merge(queue_url: url))
|
20
|
+
end
|
21
|
+
|
22
|
+
def send_message(options)
|
23
|
+
client.send_message(sanitize_message_body(options.merge(queue_url: url)))
|
24
|
+
end
|
25
|
+
|
26
|
+
def send_messages(options)
|
27
|
+
client.send_message_batch(sanitize_message_body(options.merge(queue_url: url)))
|
28
|
+
end
|
29
|
+
|
30
|
+
def receive_messages(options)
|
31
|
+
client.receive_message(options.merge(queue_url: url)).
|
32
|
+
messages.
|
33
|
+
map { |m| Message.new(client, url, m) }
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def sanitize_message_body(options)
|
39
|
+
messages = options[:entries] || [options]
|
40
|
+
|
41
|
+
messages.each do |m|
|
42
|
+
body = m[:message_body]
|
43
|
+
if body.is_a?(Hash)
|
44
|
+
m[:message_body] = JSON.dump(body)
|
45
|
+
elsif !body.is_a? String
|
46
|
+
fail ArgumentError, "The message body must be a String and you passed a #{body.class}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
options
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/shoryuken/sns_arn.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Shoryuken
|
2
2
|
class SnsArn
|
3
|
-
def initialize
|
3
|
+
def initialize(topic)
|
4
4
|
@topic = topic
|
5
5
|
end
|
6
6
|
|
@@ -13,14 +13,14 @@ module Shoryuken
|
|
13
13
|
def account_id
|
14
14
|
Shoryuken::Client.account_id.tap do |account_id|
|
15
15
|
if account_id.to_s.empty?
|
16
|
-
fail
|
16
|
+
fail 'To generate SNS ARNs, you must assign an :account_id in your Shoryuken::Client.'
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
21
|
def region
|
22
22
|
Aws.config.fetch(:region) do
|
23
|
-
fail
|
23
|
+
fail 'To generate SNS ARNs, you must include a :region in your AWS config.'
|
24
24
|
end
|
25
25
|
end
|
26
26
|
end
|
data/lib/shoryuken/util.rb
CHANGED
@@ -18,9 +18,8 @@ module Shoryuken
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def unparse_queues(queues)
|
21
|
-
queues.
|
21
|
+
queues.each_with_object({}) do |name, queue_and_weights|
|
22
22
|
queue_and_weights[name] = queue_and_weights[name].to_i + 1
|
23
|
-
queue_and_weights
|
24
23
|
end.to_a
|
25
24
|
end
|
26
25
|
|
data/lib/shoryuken/version.rb
CHANGED
data/lib/shoryuken/worker.rb
CHANGED
data/shoryuken.gemspec
CHANGED
@@ -4,27 +4,26 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'shoryuken/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name =
|
7
|
+
spec.name = 'shoryuken'
|
8
8
|
spec.version = Shoryuken::VERSION
|
9
|
-
spec.authors = [
|
10
|
-
spec.email = [
|
11
|
-
spec.description = spec.summary = %q
|
12
|
-
spec.homepage =
|
13
|
-
spec.license =
|
9
|
+
spec.authors = ['Pablo Cantero']
|
10
|
+
spec.email = ['pablo@pablocantero.com']
|
11
|
+
spec.description = spec.summary = %q(Shoryuken is a super efficient AWS SQS thread based message processor)
|
12
|
+
spec.homepage = 'https://github.com/phstc/shoryuken'
|
13
|
+
spec.license = 'LGPL-3.0'
|
14
14
|
|
15
15
|
spec.files = `git ls-files -z`.split("\x0")
|
16
16
|
spec.executables = %w[shoryuken]
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
|
-
spec.require_paths = [
|
18
|
+
spec.require_paths = ['lib']
|
19
19
|
|
20
|
-
spec.add_development_dependency
|
21
|
-
spec.add_development_dependency
|
22
|
-
spec.add_development_dependency
|
23
|
-
spec.add_development_dependency
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
20
|
+
spec.add_development_dependency 'bundler', '~> 1.6'
|
21
|
+
spec.add_development_dependency 'rake'
|
22
|
+
spec.add_development_dependency 'rspec'
|
23
|
+
spec.add_development_dependency 'pry-byebug'
|
24
|
+
spec.add_development_dependency 'nokogiri'
|
25
|
+
spec.add_development_dependency 'dotenv'
|
26
26
|
|
27
|
-
spec.add_dependency
|
28
|
-
spec.add_dependency
|
29
|
-
spec.add_dependency "celluloid", "~> 0.16.0"
|
27
|
+
spec.add_dependency 'aws-sdk-core', '~> 2.0.21'
|
28
|
+
spec.add_dependency 'celluloid', '~> 0.16.0'
|
30
29
|
end
|
@@ -48,7 +48,7 @@ describe Shoryuken::DefaultWorkerRegistry do
|
|
48
48
|
string_value: explicit_worker.to_s,
|
49
49
|
data_type: 'String' } if explicit_worker
|
50
50
|
|
51
|
-
double
|
51
|
+
double Shoryuken::Message,
|
52
52
|
body: 'test',
|
53
53
|
message_attributes: attributes,
|
54
54
|
message_id: SecureRandom.uuid
|
@@ -4,11 +4,11 @@ require 'shoryuken/fetcher'
|
|
4
4
|
|
5
5
|
describe Shoryuken::Fetcher do
|
6
6
|
let(:manager) { double Shoryuken::Manager }
|
7
|
-
let(:queue) { double
|
7
|
+
let(:queue) { double Shoryuken::Queue }
|
8
8
|
let(:queue_name) { 'default' }
|
9
9
|
|
10
10
|
let(:sqs_msg) do
|
11
|
-
double
|
11
|
+
double Shoryuken::Message,
|
12
12
|
queue_url: queue_name,
|
13
13
|
body: 'test',
|
14
14
|
message_id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e'
|
@@ -24,7 +24,7 @@ describe Shoryuken::Fetcher do
|
|
24
24
|
|
25
25
|
describe '#fetch' do
|
26
26
|
it 'calls pause when no message' do
|
27
|
-
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 1, message_attribute_names: ['All']).and_return([])
|
27
|
+
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 1, attribute_names: ['All'], message_attribute_names: ['All']).and_return([])
|
28
28
|
|
29
29
|
expect(manager).to receive(:pause_queue!).with(queue_name)
|
30
30
|
expect(manager).to receive(:dispatch)
|
@@ -33,7 +33,7 @@ describe Shoryuken::Fetcher do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
it 'assigns messages' do
|
36
|
-
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, message_attribute_names: ['All']).and_return(sqs_msg)
|
36
|
+
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, attribute_names: ['All'], message_attribute_names: ['All']).and_return(sqs_msg)
|
37
37
|
|
38
38
|
expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
|
39
39
|
expect(manager).to receive(:assign).with(queue_name, sqs_msg)
|
@@ -45,7 +45,7 @@ describe Shoryuken::Fetcher do
|
|
45
45
|
it 'assigns messages in batch' do
|
46
46
|
TestWorker.get_shoryuken_options['batch'] = true
|
47
47
|
|
48
|
-
allow(queue).to receive(:receive_messages).with(max_number_of_messages: described_class::FETCH_LIMIT, message_attribute_names: ['All']).and_return(sqs_msg)
|
48
|
+
allow(queue).to receive(:receive_messages).with(max_number_of_messages: described_class::FETCH_LIMIT, attribute_names: ['All'], message_attribute_names: ['All']).and_return(sqs_msg)
|
49
49
|
|
50
50
|
expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
|
51
51
|
expect(manager).to receive(:assign).with(queue_name, [sqs_msg])
|
@@ -58,7 +58,7 @@ describe Shoryuken::Fetcher do
|
|
58
58
|
let(:queue_name) { 'notfound' }
|
59
59
|
|
60
60
|
it 'ignores batch' do
|
61
|
-
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, message_attribute_names: ['All']).and_return(sqs_msg)
|
61
|
+
allow(queue).to receive(:receive_messages).with(max_number_of_messages: 5, attribute_names: ['All'], message_attribute_names: ['All']).and_return(sqs_msg)
|
62
62
|
|
63
63
|
expect(manager).to receive(:rebalance_queue_weight!).with(queue_name)
|
64
64
|
expect(manager).to receive(:assign).with(queue_name, sqs_msg)
|
@@ -2,10 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Shoryuken::Middleware::Server::AutoDelete do
|
4
4
|
let(:queue) { 'default' }
|
5
|
-
let(:sqs_queue) { double
|
5
|
+
let(:sqs_queue) { double Shoryuken::Queue }
|
6
6
|
|
7
7
|
def build_message
|
8
|
-
double
|
8
|
+
double Shoryuken::Message,
|
9
9
|
queue_url: queue,
|
10
10
|
body: 'test',
|
11
11
|
receipt_handle: SecureRandom.uuid
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoryuken::Middleware::Server::ExponentialBackoffRetry do
|
4
|
+
let(:queue) { 'default' }
|
5
|
+
let(:sqs_queue) { double Shoryuken::Queue }
|
6
|
+
let(:sqs_msg) { double Shoryuken::Message, queue_url: queue, body: 'test', receipt_handle: SecureRandom.uuid,
|
7
|
+
attributes: {'ApproximateReceiveCount' => 1}, message_id: SecureRandom.uuid }
|
8
|
+
|
9
|
+
before do
|
10
|
+
allow(Shoryuken::Client).to receive(:queues).with(queue).and_return(sqs_queue)
|
11
|
+
end
|
12
|
+
|
13
|
+
context 'when a job succeeds' do
|
14
|
+
it 'does not retry the job' do
|
15
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = [300, 1800]
|
16
|
+
|
17
|
+
expect(sqs_msg).not_to receive(:change_visibility)
|
18
|
+
|
19
|
+
subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) {}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context 'when a job throws an exception' do
|
24
|
+
|
25
|
+
it 'does not retry the job by default' do
|
26
|
+
expect(sqs_msg).not_to receive(:change_visibility)
|
27
|
+
|
28
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.to raise_error
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not retry the job if :retry_intervals is empty' do
|
32
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = []
|
33
|
+
|
34
|
+
expect(sqs_msg).not_to receive(:change_visibility)
|
35
|
+
|
36
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.to raise_error
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'retries the job if :retry_intervals is non-empty' do
|
40
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = [300, 1800]
|
41
|
+
|
42
|
+
allow(sqs_msg).to receive(:queue){ sqs_queue }
|
43
|
+
expect(sqs_msg).to receive(:change_visibility).with(visibility_timeout: 300)
|
44
|
+
|
45
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.not_to raise_error
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'retries the job with exponential backoff' do
|
49
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = [300, 1800]
|
50
|
+
|
51
|
+
allow(sqs_msg).to receive(:attributes){ {'ApproximateReceiveCount' => 2 } }
|
52
|
+
allow(sqs_msg).to receive(:queue){ sqs_queue }
|
53
|
+
expect(sqs_msg).to receive(:change_visibility).with(visibility_timeout: 1800)
|
54
|
+
|
55
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.not_to raise_error
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'uses the last retry interval when :receive_count exceeds the size of :retry_intervals' do
|
59
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = [300, 1800]
|
60
|
+
|
61
|
+
allow(sqs_msg).to receive(:attributes){ {'ApproximateReceiveCount' => 3 } }
|
62
|
+
allow(sqs_msg).to receive(:queue){ sqs_queue }
|
63
|
+
expect(sqs_msg).to receive(:change_visibility).with(visibility_timeout: 1800)
|
64
|
+
|
65
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.not_to raise_error
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'limits the visibility timeout to 12 hours from receipt of message' do
|
69
|
+
TestWorker.get_shoryuken_options['retry_intervals'] = [86400]
|
70
|
+
|
71
|
+
allow(sqs_msg).to receive(:queue){ sqs_queue }
|
72
|
+
expect(sqs_msg).to receive(:change_visibility).with(visibility_timeout: 43198)
|
73
|
+
|
74
|
+
expect { subject.call(TestWorker.new, queue, sqs_msg, sqs_msg.body) { raise } }.not_to raise_error
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -2,10 +2,10 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Shoryuken::Middleware::Server::Timing do
|
4
4
|
let(:queue) { 'default' }
|
5
|
-
let(:sqs_queue) { double
|
5
|
+
let(:sqs_queue) { double Shoryuken::Queue, visibility_timeout: 60 }
|
6
6
|
|
7
7
|
let(:sqs_msg) do
|
8
|
-
double
|
8
|
+
double Shoryuken::Message,
|
9
9
|
queue_url: queue,
|
10
10
|
body: 'test',
|
11
11
|
message_id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e'
|
@@ -4,11 +4,11 @@ require 'shoryuken/manager'
|
|
4
4
|
|
5
5
|
describe Shoryuken::Processor do
|
6
6
|
let(:manager) { double Shoryuken::Manager, processor_done: nil }
|
7
|
-
let(:sqs_queue) { double
|
7
|
+
let(:sqs_queue) { double Shoryuken::Queue, visibility_timeout: 30 }
|
8
8
|
let(:queue) { 'default' }
|
9
9
|
|
10
10
|
let(:sqs_msg) do
|
11
|
-
double
|
11
|
+
double Shoryuken::Message,
|
12
12
|
queue_url: queue,
|
13
13
|
body: 'test',
|
14
14
|
message_attributes: {},
|
@@ -38,7 +38,7 @@ describe Shoryuken::Processor do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'parses the body calling the proc' do
|
41
|
-
TestWorker.get_shoryuken_options['body_parser'] =
|
41
|
+
TestWorker.get_shoryuken_options['body_parser'] = proc { |sqs_msg| "*#{sqs_msg.body}*" }
|
42
42
|
|
43
43
|
expect_any_instance_of(TestWorker).to receive(:perform).with(sqs_msg, '*test*')
|
44
44
|
|
@@ -207,15 +207,15 @@ describe Shoryuken::Processor do
|
|
207
207
|
|
208
208
|
context 'when shoryuken_class header' do
|
209
209
|
let(:sqs_msg) do
|
210
|
-
double
|
210
|
+
double Shoryuken::Message,
|
211
211
|
queue_url: queue,
|
212
212
|
body: 'test',
|
213
213
|
message_attributes: {
|
214
214
|
'shoryuken_class' => {
|
215
215
|
string_value: TestWorker.to_s,
|
216
216
|
data_type: 'String' }},
|
217
|
-
|
218
|
-
|
217
|
+
message_id: SecureRandom.uuid,
|
218
|
+
receipt_handle: SecureRandom.uuid
|
219
219
|
end
|
220
220
|
|
221
221
|
it 'performs without delete' do
|
@@ -244,7 +244,7 @@ describe Shoryuken::Processor do
|
|
244
244
|
|
245
245
|
context 'when the worker takes a long time', slow: true do
|
246
246
|
it 'extends the message invisibility to prevent it from being dequeued concurrently' do
|
247
|
-
TestWorker.get_shoryuken_options['body_parser'] =
|
247
|
+
TestWorker.get_shoryuken_options['body_parser'] = proc do
|
248
248
|
sleep visibility_timeout
|
249
249
|
'test'
|
250
250
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Shoryuken::Queue do
|
4
|
+
let(:credentials) { Aws::Credentials.new('access_key_id', 'secret_access_key') }
|
5
|
+
let(:sqs) { Aws::SQS::Client.new(stub_responses: true, credentials: credentials) }
|
6
|
+
let(:queue_name) { 'shoryuken' }
|
7
|
+
let(:queue_url) { 'https://eu-west-1.amazonaws.com:6059/123456789012/shoryuken' }
|
8
|
+
|
9
|
+
subject { described_class.new(sqs, queue_name) }
|
10
|
+
|
11
|
+
describe '#send_message' do
|
12
|
+
context 'when body is invalid' do
|
13
|
+
it 'raises ArgumentError for nil' do
|
14
|
+
expect {
|
15
|
+
subject.send_message(message_body: nil)
|
16
|
+
}.to raise_error(ArgumentError, 'The message body must be a String and you passed a NilClass')
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'raises ArgumentError for Fixnum' do
|
20
|
+
expect {
|
21
|
+
subject.send_message(message_body: 1)
|
22
|
+
}.to raise_error(ArgumentError, 'The message body must be a String and you passed a Fixnum')
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#send_messages' do
|
28
|
+
context 'when body is invalid' do
|
29
|
+
it 'raises ArgumentError for nil' do
|
30
|
+
expect {
|
31
|
+
subject.send_messages(entries: [message_body: nil])
|
32
|
+
}.to raise_error(ArgumentError, 'The message body must be a String and you passed a NilClass')
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'raises ArgumentError for Fixnum' do
|
36
|
+
expect {
|
37
|
+
subject.send_messages(entries: [message_body: 1])
|
38
|
+
}.to raise_error(ArgumentError, 'The message body must be a String and you passed a Fixnum')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/spec/shoryuken/util_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe 'Shoryuken::Util' do
|
|
17
17
|
|
18
18
|
describe '#worker_name' do
|
19
19
|
let(:sqs_msg) do
|
20
|
-
double
|
20
|
+
double Shoryuken::Message, message_id: 'fc754df7-9cc2-4c41-96ca-5996a44b771e', message_attributes: {}
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns Shoryuken worker name' do
|
@@ -66,19 +66,6 @@ describe 'Shoryuken::Worker' do
|
|
66
66
|
TestWorker.perform_async('message')
|
67
67
|
end
|
68
68
|
|
69
|
-
it 'enqueues a message given as hash' do
|
70
|
-
expect(sqs_queue).to receive(:send_message).with(
|
71
|
-
message_attributes: {
|
72
|
-
'shoryuken_class' => {
|
73
|
-
string_value: TestWorker.to_s,
|
74
|
-
data_type: 'String'
|
75
|
-
}
|
76
|
-
},
|
77
|
-
message_body: '{"field":"part1","other_field":"part2"}')
|
78
|
-
|
79
|
-
TestWorker.perform_async(field: 'part1', other_field: 'part2')
|
80
|
-
end
|
81
|
-
|
82
69
|
it 'enqueues a message with options' do
|
83
70
|
expect(sqs_queue).to receive(:send_message).with(
|
84
71
|
delay_seconds: 60,
|
data/spec/spec_helper.rb
CHANGED
@@ -42,9 +42,6 @@ RSpec.configure do |config|
|
|
42
42
|
config.filter_run_excluding slow: true unless ENV['SPEC_ALL']
|
43
43
|
|
44
44
|
config.before do
|
45
|
-
# remove doubles, preventing:
|
46
|
-
# Double "Queue" was originally created in one example but has leaked into another example and can no longer be used.
|
47
|
-
# rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.
|
48
45
|
Shoryuken::Client.class_variable_set :@@queues, {}
|
49
46
|
Shoryuken::Client.class_variable_set :@@visibility_timeouts, {}
|
50
47
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
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.1
|
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-03-
|
11
|
+
date: 2015-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -98,30 +98,16 @@ dependencies:
|
|
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
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: aws-sdk-resources
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - '='
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: 2.0.21.pre
|
118
|
-
type: :runtime
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - '='
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: 2.0.21.pre
|
125
111
|
- !ruby/object:Gem::Dependency
|
126
112
|
name: celluloid
|
127
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,6 +133,7 @@ files:
|
|
147
133
|
- .gitignore
|
148
134
|
- .hound.yml
|
149
135
|
- .rspec
|
136
|
+
- .rubocop.yml
|
150
137
|
- .travis.yml
|
151
138
|
- Gemfile
|
152
139
|
- LICENSE.txt
|
@@ -166,11 +153,14 @@ files:
|
|
166
153
|
- lib/shoryuken/launcher.rb
|
167
154
|
- lib/shoryuken/logging.rb
|
168
155
|
- lib/shoryuken/manager.rb
|
156
|
+
- lib/shoryuken/message.rb
|
169
157
|
- lib/shoryuken/middleware/chain.rb
|
170
158
|
- lib/shoryuken/middleware/server/active_record.rb
|
171
159
|
- lib/shoryuken/middleware/server/auto_delete.rb
|
160
|
+
- lib/shoryuken/middleware/server/exponential_backoff_retry.rb
|
172
161
|
- lib/shoryuken/middleware/server/timing.rb
|
173
162
|
- lib/shoryuken/processor.rb
|
163
|
+
- lib/shoryuken/queue.rb
|
174
164
|
- lib/shoryuken/sns_arn.rb
|
175
165
|
- lib/shoryuken/topic.rb
|
176
166
|
- lib/shoryuken/util.rb
|
@@ -188,8 +178,10 @@ files:
|
|
188
178
|
- spec/shoryuken/manager_spec.rb
|
189
179
|
- spec/shoryuken/middleware/chain_spec.rb
|
190
180
|
- spec/shoryuken/middleware/server/auto_delete_spec.rb
|
181
|
+
- spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb
|
191
182
|
- spec/shoryuken/middleware/server/timing_spec.rb
|
192
183
|
- spec/shoryuken/processor_spec.rb
|
184
|
+
- spec/shoryuken/queue_spec.rb
|
193
185
|
- spec/shoryuken/sns_arn_spec.rb
|
194
186
|
- spec/shoryuken/topic_spec.rb
|
195
187
|
- spec/shoryuken/util_spec.rb
|
@@ -230,8 +222,10 @@ test_files:
|
|
230
222
|
- spec/shoryuken/manager_spec.rb
|
231
223
|
- spec/shoryuken/middleware/chain_spec.rb
|
232
224
|
- spec/shoryuken/middleware/server/auto_delete_spec.rb
|
225
|
+
- spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb
|
233
226
|
- spec/shoryuken/middleware/server/timing_spec.rb
|
234
227
|
- spec/shoryuken/processor_spec.rb
|
228
|
+
- spec/shoryuken/queue_spec.rb
|
235
229
|
- spec/shoryuken/sns_arn_spec.rb
|
236
230
|
- spec/shoryuken/topic_spec.rb
|
237
231
|
- spec/shoryuken/util_spec.rb
|