shoryuken 1.0.0 → 1.0.1
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 +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
|