shoryuken 4.0.1 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.rubocop.yml +1 -1
- data/.travis.yml +6 -5
- data/CHANGELOG.md +27 -0
- data/lib/shoryuken/environment_loader.rb +4 -3
- data/lib/shoryuken/fetcher.rb +19 -13
- data/lib/shoryuken/launcher.rb +1 -1
- data/lib/shoryuken/manager.rb +4 -4
- data/lib/shoryuken/options.rb +132 -187
- data/lib/shoryuken/polling/base.rb +1 -3
- data/lib/shoryuken/polling/strict_priority.rb +2 -1
- data/lib/shoryuken/polling/weighted_round_robin.rb +2 -1
- data/lib/shoryuken/queue.rb +3 -3
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +3 -3
- data/lib/shoryuken.rb +9 -4
- data/shoryuken.gemspec +0 -1
- data/spec/shoryuken/environment_loader_spec.rb +24 -1
- data/spec/shoryuken/fetcher_spec.rb +17 -2
- data/spec/shoryuken/manager_spec.rb +35 -2
- data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +1 -1
- data/spec/shoryuken/options_spec.rb +38 -20
- data/spec/shoryuken/polling/strict_priority_spec.rb +8 -0
- data/spec/shoryuken/polling/weighted_round_robin_spec.rb +8 -0
- data/spec/shoryuken/processor_spec.rb +4 -4
- data/spec/shoryuken/queue_spec.rb +16 -3
- data/spec/spec_helper.rb +2 -2
- metadata +3 -17
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: ce36f4dac1c75e383185df15db196aec57c968dda1a5823b8d944ad4a9675906
|
|
4
|
+
data.tar.gz: a460a585e97a6c0a3432f6b28bec254d494900672a06bffbd7461e830a8de0cf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 833bab295345b25456f617f36e4ec2f2cfd0d823a01ddb87d8f528597ab79b91ce0ae8c67b47ffc2a9d1400f0a5cf62df3125fbdfbb49abd3a5e4a5eb3b7b0ee
|
|
7
|
+
data.tar.gz: 91a4355cd9e180f006e8768bde9627c1df9cf0057d294bdfcb422f479de2ef1784aa5b904c7b97dac8ed7bb7b9879bdea56eb4cd00d51ff456d3b4555f88c991
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
|
@@ -3,10 +3,11 @@ language: ruby
|
|
|
3
3
|
rvm:
|
|
4
4
|
- 2.0.0
|
|
5
5
|
- 2.1.10
|
|
6
|
-
- 2.2.
|
|
7
|
-
- 2.3.
|
|
8
|
-
- 2.4.
|
|
9
|
-
- 2.5.
|
|
6
|
+
- 2.2.10
|
|
7
|
+
- 2.3.8
|
|
8
|
+
- 2.4.4
|
|
9
|
+
- 2.5.1
|
|
10
|
+
- 2.6.3
|
|
10
11
|
|
|
11
12
|
notifications:
|
|
12
13
|
email:
|
|
@@ -23,7 +24,7 @@ env:
|
|
|
23
24
|
script: bundle exec rspec spec
|
|
24
25
|
|
|
25
26
|
before_install:
|
|
26
|
-
- gem
|
|
27
|
+
- gem install bundler -v '< 2'
|
|
27
28
|
|
|
28
29
|
after_success:
|
|
29
30
|
- bundle exec codeclimate-test-reporter
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
## [v5.0.0] - 2019-06-18
|
|
2
|
+
|
|
3
|
+
- Fix bug where empty queues were not paused in batch processing mode
|
|
4
|
+
- [#569](https://github.com/phstc/shoryuken/pull/569)
|
|
5
|
+
|
|
6
|
+
- Preserve batch limit when receiving messages from a FIFO queue
|
|
7
|
+
- [#563](https://github.com/phstc/shoryuken/pull/563)
|
|
8
|
+
|
|
9
|
+
- Replace static options with instance options
|
|
10
|
+
- [#534](https://github.com/phstc/shoryuken/pull/534)
|
|
11
|
+
|
|
12
|
+
## [v4.0.3] - 2019-01-06
|
|
13
|
+
|
|
14
|
+
- Support delay per processing group
|
|
15
|
+
- [#543](https://github.com/phstc/shoryuken/pull/543)
|
|
16
|
+
|
|
17
|
+
## [v4.0.2] - 2018-11-26
|
|
18
|
+
|
|
19
|
+
- Fix the delegated methods to public warning
|
|
20
|
+
- [#536](https://github.com/phstc/shoryuken/pull/536)
|
|
21
|
+
|
|
22
|
+
- Specify exception class to `raise_error` matcher warning
|
|
23
|
+
- [#537](https://github.com/phstc/shoryuken/pull/537)
|
|
24
|
+
|
|
25
|
+
- Fix spelling of "visibility"
|
|
26
|
+
- [#538](https://github.com/phstc/shoryuken/pull/538)
|
|
27
|
+
|
|
1
28
|
## [v4.0.1] - 2018-11-21
|
|
2
29
|
|
|
3
30
|
- Allow caching visibility_timeout lookups
|
|
@@ -99,7 +99,7 @@ module Shoryuken
|
|
|
99
99
|
|
|
100
100
|
def prefix_active_job_queue_names
|
|
101
101
|
return unless Shoryuken.active_job?
|
|
102
|
-
return unless Shoryuken.active_job_queue_name_prefixing
|
|
102
|
+
return unless Shoryuken.active_job_queue_name_prefixing?
|
|
103
103
|
|
|
104
104
|
Shoryuken.options[:queues].to_a.map! do |queue_name, weight|
|
|
105
105
|
prefix_active_job_queue_name(queue_name, weight)
|
|
@@ -122,7 +122,7 @@ module Shoryuken
|
|
|
122
122
|
|
|
123
123
|
def parse_queues
|
|
124
124
|
if Shoryuken.options[:queues].to_a.any?
|
|
125
|
-
Shoryuken.add_group('default', Shoryuken.options
|
|
125
|
+
Shoryuken.add_group('default', Shoryuken.options[:concurrency])
|
|
126
126
|
|
|
127
127
|
Shoryuken.options[:queues].to_a.each do |queue, weight|
|
|
128
128
|
parse_queue(queue, weight, 'default')
|
|
@@ -130,7 +130,8 @@ module Shoryuken
|
|
|
130
130
|
end
|
|
131
131
|
|
|
132
132
|
Shoryuken.options[:groups].to_a.each do |group, options|
|
|
133
|
-
Shoryuken.add_group(group, options
|
|
133
|
+
Shoryuken.add_group(group, options[:concurrency], delay: options[:delay])
|
|
134
|
+
|
|
134
135
|
options[:queues].to_a.each do |queue, weight|
|
|
135
136
|
parse_queue(queue, weight, group)
|
|
136
137
|
end
|
data/lib/shoryuken/fetcher.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Shoryuken
|
|
|
14
14
|
|
|
15
15
|
logger.debug { "Looking for new messages in #{queue}" }
|
|
16
16
|
|
|
17
|
-
sqs_msgs = Array(receive_messages(queue,
|
|
17
|
+
sqs_msgs = Array(receive_messages(queue, limit))
|
|
18
18
|
|
|
19
19
|
logger.debug { "Found #{sqs_msgs.size} messages for #{queue.name}" } unless sqs_msgs.empty?
|
|
20
20
|
logger.debug { "Fetcher for #{queue} completed in #{elapsed(started_at)} ms" }
|
|
@@ -49,16 +49,7 @@ module Shoryuken
|
|
|
49
49
|
|
|
50
50
|
shoryuken_queue = Shoryuken::Client.queues(queue.name)
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
# if we set max_number_of_messages greater than 1,
|
|
54
|
-
# SQS may return more than one message for the same message group
|
|
55
|
-
# since Shoryuken uses threads, it will try to process more than one at once
|
|
56
|
-
# > The message group ID is the tag that specifies that a message belongs to a specific message group.
|
|
57
|
-
# > Messages that belong to the same message group are always processed one by one,
|
|
58
|
-
# > in a strict order relative to the message group
|
|
59
|
-
# > (however, messages that belong to different message groups might be processed out of order).
|
|
60
|
-
# > https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html
|
|
61
|
-
options[:max_number_of_messages] = shoryuken_queue.fifo? ? 1 : max_number_of_messages(limit, options)
|
|
52
|
+
options[:max_number_of_messages] = max_number_of_messages(shoryuken_queue, limit, options)
|
|
62
53
|
options[:message_attribute_names] = %w[All]
|
|
63
54
|
options[:attribute_names] = %w[All]
|
|
64
55
|
|
|
@@ -67,7 +58,18 @@ module Shoryuken
|
|
|
67
58
|
shoryuken_queue.receive_messages(options)
|
|
68
59
|
end
|
|
69
60
|
|
|
70
|
-
def max_number_of_messages(limit, options)
|
|
61
|
+
def max_number_of_messages(shoryuken_queue, limit, options)
|
|
62
|
+
# For FIFO queues we want to make sure we process one message per group at a time
|
|
63
|
+
# if we set max_number_of_messages greater than 1,
|
|
64
|
+
# SQS may return more than one message for the same message group
|
|
65
|
+
# since Shoryuken uses threads, it will try to process more than one message at once
|
|
66
|
+
# > The message group ID is the tag that specifies that a message belongs to a specific message group.
|
|
67
|
+
# > Messages that belong to the same message group are always processed one by one,
|
|
68
|
+
# > in a strict order relative to the message group
|
|
69
|
+
# > (however, messages that belong to different message groups might be processed out of order).
|
|
70
|
+
# > https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html
|
|
71
|
+
limit = 1 if shoryuken_queue.fifo? && !batched_queue?(shoryuken_queue)
|
|
72
|
+
|
|
71
73
|
[limit, FETCH_LIMIT, options[:max_number_of_messages]].compact.min
|
|
72
74
|
end
|
|
73
75
|
|
|
@@ -77,5 +79,9 @@ module Shoryuken
|
|
|
77
79
|
|
|
78
80
|
options.to_h.dup
|
|
79
81
|
end
|
|
82
|
+
|
|
83
|
+
def batched_queue?(queue)
|
|
84
|
+
Shoryuken.worker_registry.batch_receive_messages?(queue.name)
|
|
85
|
+
end
|
|
80
86
|
end
|
|
81
|
-
end
|
|
87
|
+
end
|
data/lib/shoryuken/launcher.rb
CHANGED
|
@@ -72,7 +72,7 @@ module Shoryuken
|
|
|
72
72
|
Shoryuken.groups.map do |group, options|
|
|
73
73
|
Shoryuken::Manager.new(
|
|
74
74
|
Shoryuken::Fetcher.new(group),
|
|
75
|
-
Shoryuken.polling_strategy(group).new(options[:queues]),
|
|
75
|
+
Shoryuken.polling_strategy(group).new(options[:queues], Shoryuken.delay(group)),
|
|
76
76
|
options[:concurrency],
|
|
77
77
|
executor
|
|
78
78
|
)
|
data/lib/shoryuken/manager.rb
CHANGED
|
@@ -43,8 +43,8 @@ module Shoryuken
|
|
|
43
43
|
logger.debug { "Ready: #{ready}, Busy: #{busy}, Active Queues: #{@polling_strategy.active_queues}" }
|
|
44
44
|
|
|
45
45
|
batched_queue?(queue) ? dispatch_batch(queue) : dispatch_single_messages(queue)
|
|
46
|
-
rescue =>
|
|
47
|
-
handle_dispatch_error(
|
|
46
|
+
rescue => e
|
|
47
|
+
handle_dispatch_error(e)
|
|
48
48
|
ensure
|
|
49
49
|
dispatch_loop
|
|
50
50
|
end
|
|
@@ -74,9 +74,9 @@ module Shoryuken
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def dispatch_batch(queue)
|
|
77
|
-
|
|
77
|
+
batch = @fetcher.fetch(queue, BATCH_LIMIT)
|
|
78
78
|
@polling_strategy.messages_found(queue.name, batch.size)
|
|
79
|
-
assign(queue.name, patch_batch!(batch))
|
|
79
|
+
assign(queue.name, patch_batch!(batch)) if batch.any?
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
def dispatch_single_messages(queue)
|
data/lib/shoryuken/options.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Shoryuken
|
|
|
4
4
|
concurrency: 25,
|
|
5
5
|
queues: [],
|
|
6
6
|
aws: {},
|
|
7
|
-
delay: 0,
|
|
7
|
+
delay: 0.0,
|
|
8
8
|
timeout: 8,
|
|
9
9
|
lifecycle_events: {
|
|
10
10
|
startup: [],
|
|
@@ -14,221 +14,166 @@ module Shoryuken
|
|
|
14
14
|
}
|
|
15
15
|
}.freeze
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
defined?(::ActiveJob)
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def add_group(group, concurrency)
|
|
34
|
-
groups[group] ||= {
|
|
35
|
-
concurrency: concurrency,
|
|
36
|
-
queues: []
|
|
37
|
-
}
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def groups
|
|
41
|
-
@@groups
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def add_queue(queue, weight, group)
|
|
45
|
-
weight.times do
|
|
46
|
-
groups[group][:queues] << queue
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def ungrouped_queues
|
|
51
|
-
groups.values.flat_map { |options| options[:queues] }
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def worker_registry
|
|
55
|
-
@@worker_registry
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def worker_registry=(worker_registry)
|
|
59
|
-
@@worker_registry = worker_registry
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def worker_executor
|
|
63
|
-
@@worker_executor
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def worker_executor=(worker_executor)
|
|
67
|
-
@@worker_executor = worker_executor
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def launcher_executor
|
|
71
|
-
@@launcher_executor
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
def launcher_executor=(launcher_executor)
|
|
75
|
-
@@launcher_executor = launcher_executor
|
|
76
|
-
end
|
|
17
|
+
attr_accessor :active_job_queue_name_prefixing, :cache_visibility_timeout, :default_worker_options, :groups,
|
|
18
|
+
:launcher_executor, :sqs_client, :sqs_client_receive_message_opts,
|
|
19
|
+
:start_callback, :worker_executor, :worker_registry
|
|
20
|
+
|
|
21
|
+
def initialize
|
|
22
|
+
self.groups = {}
|
|
23
|
+
self.worker_registry = DefaultWorkerRegistry.new
|
|
24
|
+
self.active_job_queue_name_prefixing = false
|
|
25
|
+
self.worker_executor = Worker::DefaultExecutor
|
|
26
|
+
self.cache_visibility_timeout = false
|
|
27
|
+
# this is needed for keeping backward compatibility
|
|
28
|
+
@sqs_client_receive_message_opts ||= {}
|
|
29
|
+
end
|
|
77
30
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
case strategy
|
|
82
|
-
when 'WeightedRoundRobin', nil # Default case
|
|
83
|
-
Polling::WeightedRoundRobin
|
|
84
|
-
when 'StrictPriority'
|
|
85
|
-
Polling::StrictPriority
|
|
86
|
-
when Class
|
|
87
|
-
strategy
|
|
88
|
-
else
|
|
89
|
-
raise ArgumentError, "#{strategy} is not a valid polling_strategy"
|
|
90
|
-
end
|
|
91
|
-
end
|
|
31
|
+
def active_job?
|
|
32
|
+
defined?(::ActiveJob)
|
|
33
|
+
end
|
|
92
34
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
35
|
+
def add_group(group, concurrency = nil, delay: nil)
|
|
36
|
+
concurrency ||= options[:concurrency]
|
|
37
|
+
delay ||= options[:delay]
|
|
96
38
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
39
|
+
groups[group] ||= {
|
|
40
|
+
concurrency: concurrency,
|
|
41
|
+
delay: delay,
|
|
42
|
+
queues: []
|
|
43
|
+
}
|
|
44
|
+
end
|
|
100
45
|
|
|
101
|
-
|
|
102
|
-
|
|
46
|
+
def add_queue(queue, weight, group)
|
|
47
|
+
weight.times do
|
|
48
|
+
groups[group][:queues] << queue
|
|
103
49
|
end
|
|
50
|
+
end
|
|
104
51
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
52
|
+
def ungrouped_queues
|
|
53
|
+
groups.values.flat_map { |options| options[:queues] }
|
|
54
|
+
end
|
|
108
55
|
|
|
109
|
-
|
|
110
|
-
|
|
56
|
+
def polling_strategy(group)
|
|
57
|
+
strategy = (group == 'default' ? options : options[:groups].to_h[group]).to_h[:polling_strategy]
|
|
58
|
+
case strategy
|
|
59
|
+
when 'WeightedRoundRobin', nil # Default case
|
|
60
|
+
Polling::WeightedRoundRobin
|
|
61
|
+
when 'StrictPriority'
|
|
62
|
+
Polling::StrictPriority
|
|
63
|
+
when Class
|
|
64
|
+
strategy
|
|
65
|
+
else
|
|
66
|
+
raise ArgumentError, "#{strategy} is not a valid polling_strategy"
|
|
111
67
|
end
|
|
68
|
+
end
|
|
112
69
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
70
|
+
def delay(group)
|
|
71
|
+
groups[group].to_h.fetch(:delay, options[:delay]).to_f
|
|
72
|
+
end
|
|
116
73
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
74
|
+
def sqs_client
|
|
75
|
+
@sqs_client ||= Aws::SQS::Client.new
|
|
76
|
+
end
|
|
120
77
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
78
|
+
def sqs_client_receive_message_opts=(sqs_client_receive_message_opts)
|
|
79
|
+
@sqs_client_receive_message_opts['default'] = sqs_client_receive_message_opts
|
|
80
|
+
end
|
|
124
81
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
82
|
+
def options
|
|
83
|
+
@options ||= DEFAULTS.dup
|
|
84
|
+
end
|
|
128
85
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
86
|
+
def logger
|
|
87
|
+
Shoryuken::Logging.logger
|
|
88
|
+
end
|
|
132
89
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
90
|
+
def register_worker(*args)
|
|
91
|
+
worker_registry.register_worker(*args)
|
|
92
|
+
end
|
|
136
93
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
94
|
+
def configure_server
|
|
95
|
+
yield self if server?
|
|
96
|
+
end
|
|
140
97
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
98
|
+
def server_middleware
|
|
99
|
+
@_server_chain ||= default_server_middleware
|
|
100
|
+
yield @_server_chain if block_given?
|
|
101
|
+
@_server_chain
|
|
102
|
+
end
|
|
144
103
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
104
|
+
def configure_client
|
|
105
|
+
yield self unless server?
|
|
106
|
+
end
|
|
148
107
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
108
|
+
def client_middleware
|
|
109
|
+
@_client_chain ||= default_client_middleware
|
|
110
|
+
yield @_client_chain if block_given?
|
|
111
|
+
@_client_chain
|
|
112
|
+
end
|
|
154
113
|
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
114
|
+
def default_worker_options
|
|
115
|
+
@default_worker_options ||= {
|
|
116
|
+
'queue' => 'default',
|
|
117
|
+
'delete' => false,
|
|
118
|
+
'auto_delete' => false,
|
|
119
|
+
'auto_visibility_timeout' => false,
|
|
120
|
+
'retry_intervals' => nil,
|
|
121
|
+
'batch' => false
|
|
122
|
+
}
|
|
123
|
+
end
|
|
158
124
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
@@client_chain
|
|
163
|
-
end
|
|
125
|
+
def on_start(&block)
|
|
126
|
+
self.start_callback = block
|
|
127
|
+
end
|
|
164
128
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
'delete' => false,
|
|
169
|
-
'auto_delete' => false,
|
|
170
|
-
'auto_visibility_timeout' => false,
|
|
171
|
-
'retry_intervals' => nil,
|
|
172
|
-
'batch' => false
|
|
173
|
-
}
|
|
174
|
-
end
|
|
129
|
+
def on_stop(&block)
|
|
130
|
+
self.stop_callback = block
|
|
131
|
+
end
|
|
175
132
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
133
|
+
# Register a block to run at a point in the Shoryuken lifecycle.
|
|
134
|
+
# :startup, :quiet or :shutdown are valid events.
|
|
135
|
+
#
|
|
136
|
+
# Shoryuken.configure_server do |config|
|
|
137
|
+
# config.on(:shutdown) do
|
|
138
|
+
# puts "Goodbye cruel world!"
|
|
139
|
+
# end
|
|
140
|
+
# end
|
|
141
|
+
def on(event, &block)
|
|
142
|
+
fail ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
|
|
143
|
+
fail ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
|
|
144
|
+
|
|
145
|
+
options[:lifecycle_events][event] << block
|
|
146
|
+
end
|
|
179
147
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
148
|
+
def server?
|
|
149
|
+
defined?(Shoryuken::CLI)
|
|
150
|
+
end
|
|
183
151
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
152
|
+
def cache_visibility_timeout?
|
|
153
|
+
@cache_visibility_timeout
|
|
154
|
+
end
|
|
187
155
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
# Shoryuken.configure_server do |config|
|
|
192
|
-
# config.on(:shutdown) do
|
|
193
|
-
# puts "Goodbye cruel world!"
|
|
194
|
-
# end
|
|
195
|
-
# end
|
|
196
|
-
def on(event, &block)
|
|
197
|
-
fail ArgumentError, "Symbols only please: #{event}" unless event.is_a?(Symbol)
|
|
198
|
-
fail ArgumentError, "Invalid event name: #{event}" unless options[:lifecycle_events].key?(event)
|
|
199
|
-
options[:lifecycle_events][event] << block
|
|
200
|
-
end
|
|
156
|
+
def active_job_queue_name_prefixing?
|
|
157
|
+
@active_job_queue_name_prefixing
|
|
158
|
+
end
|
|
201
159
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
end
|
|
160
|
+
private
|
|
161
|
+
|
|
162
|
+
def default_server_middleware
|
|
163
|
+
Middleware::Chain.new do |m|
|
|
164
|
+
m.add Middleware::Server::Timing
|
|
165
|
+
m.add Middleware::Server::ExponentialBackoffRetry
|
|
166
|
+
m.add Middleware::Server::AutoDelete
|
|
167
|
+
m.add Middleware::Server::AutoExtendVisibility
|
|
168
|
+
if defined?(::ActiveRecord::Base)
|
|
169
|
+
require 'shoryuken/middleware/server/active_record'
|
|
170
|
+
m.add Middleware::Server::ActiveRecord
|
|
214
171
|
end
|
|
215
172
|
end
|
|
173
|
+
end
|
|
216
174
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
end
|
|
220
|
-
|
|
221
|
-
def server?
|
|
222
|
-
defined?(Shoryuken::CLI)
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def cache_visiblity_timeout?
|
|
226
|
-
@@cache_visiblity_timeout
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
def cache_visiblity_timeout=(cache_visiblity_timeout)
|
|
230
|
-
@@cache_visiblity_timeout = cache_visiblity_timeout
|
|
231
|
-
end
|
|
175
|
+
def default_client_middleware
|
|
176
|
+
Middleware::Chain.new
|
|
232
177
|
end
|
|
233
178
|
end
|
|
234
179
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module Shoryuken
|
|
2
2
|
module Polling
|
|
3
3
|
class StrictPriority < BaseStrategy
|
|
4
|
-
def initialize(queues)
|
|
4
|
+
def initialize(queues, delay = nil)
|
|
5
5
|
# Priority ordering of the queues, highest priority first
|
|
6
6
|
@queues = queues
|
|
7
7
|
.group_by { |q| q }
|
|
@@ -12,6 +12,7 @@ module Shoryuken
|
|
|
12
12
|
@paused_until = queues
|
|
13
13
|
.each_with_object({}) { |queue, h| h[queue] = Time.at(0) }
|
|
14
14
|
|
|
15
|
+
@delay = delay
|
|
15
16
|
# Start queues at 0
|
|
16
17
|
reset_next_queue
|
|
17
18
|
end
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
module Shoryuken
|
|
2
2
|
module Polling
|
|
3
3
|
class WeightedRoundRobin < BaseStrategy
|
|
4
|
-
def initialize(queues)
|
|
4
|
+
def initialize(queues, delay = nil)
|
|
5
5
|
@initial_queues = queues
|
|
6
6
|
@queues = queues.dup.uniq
|
|
7
7
|
@paused_queues = []
|
|
8
|
+
@delay = delay
|
|
8
9
|
end
|
|
9
10
|
|
|
10
11
|
def next_queue
|
data/lib/shoryuken/queue.rb
CHANGED
|
@@ -14,9 +14,9 @@ module Shoryuken
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def visibility_timeout
|
|
17
|
-
# Always lookup for the latest
|
|
17
|
+
# Always lookup for the latest visibility when cache is disabled
|
|
18
18
|
# setting it to nil, forces re-lookup
|
|
19
|
-
@_visibility_timeout = nil unless Shoryuken.
|
|
19
|
+
@_visibility_timeout = nil unless Shoryuken.cache_visibility_timeout?
|
|
20
20
|
@_visibility_timeout ||= queue_attributes.attributes[VISIBILITY_TIMEOUT_ATTR].to_i
|
|
21
21
|
end
|
|
22
22
|
|
|
@@ -66,7 +66,7 @@ module Shoryuken
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
def set_name_and_url(name_or_url)
|
|
69
|
-
if name_or_url.
|
|
69
|
+
if name_or_url.include?('://')
|
|
70
70
|
set_by_url(name_or_url)
|
|
71
71
|
|
|
72
72
|
# anticipate the fifo? checker for validating the queue URL
|
data/lib/shoryuken/version.rb
CHANGED
data/lib/shoryuken/worker.rb
CHANGED
|
@@ -17,9 +17,9 @@ module Shoryuken
|
|
|
17
17
|
alias_method :perform_at, :perform_in
|
|
18
18
|
|
|
19
19
|
def server_middleware
|
|
20
|
-
@
|
|
21
|
-
yield @
|
|
22
|
-
@
|
|
20
|
+
@_server_chain ||= Shoryuken.server_middleware.dup
|
|
21
|
+
yield @_server_chain if block_given?
|
|
22
|
+
@_server_chain
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def shoryuken_options(opts = {})
|
data/lib/shoryuken.rb
CHANGED
|
@@ -41,8 +41,12 @@ require 'shoryuken/options'
|
|
|
41
41
|
module Shoryuken
|
|
42
42
|
extend SingleForwardable
|
|
43
43
|
|
|
44
|
+
def self.shoryuken_options
|
|
45
|
+
@_shoryuken_options ||= Shoryuken::Options.new
|
|
46
|
+
end
|
|
47
|
+
|
|
44
48
|
def_delegators(
|
|
45
|
-
:
|
|
49
|
+
:shoryuken_options,
|
|
46
50
|
:active_job?,
|
|
47
51
|
:add_group,
|
|
48
52
|
:groups,
|
|
@@ -59,7 +63,7 @@ module Shoryuken
|
|
|
59
63
|
:start_callback=,
|
|
60
64
|
:stop_callback,
|
|
61
65
|
:stop_callback=,
|
|
62
|
-
:active_job_queue_name_prefixing
|
|
66
|
+
:active_job_queue_name_prefixing?,
|
|
63
67
|
:active_job_queue_name_prefixing=,
|
|
64
68
|
:sqs_client,
|
|
65
69
|
:sqs_client=,
|
|
@@ -78,8 +82,9 @@ module Shoryuken
|
|
|
78
82
|
:on_start,
|
|
79
83
|
:on_stop,
|
|
80
84
|
:on,
|
|
81
|
-
:
|
|
82
|
-
:
|
|
85
|
+
:cache_visibility_timeout?,
|
|
86
|
+
:cache_visibility_timeout=,
|
|
87
|
+
:delay
|
|
83
88
|
)
|
|
84
89
|
end
|
|
85
90
|
|
data/shoryuken.gemspec
CHANGED
|
@@ -17,7 +17,6 @@ Gem::Specification.new do |spec|
|
|
|
17
17
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
18
18
|
spec.require_paths = ['lib']
|
|
19
19
|
|
|
20
|
-
spec.add_development_dependency 'bundler', '~> 1.6'
|
|
21
20
|
spec.add_development_dependency 'dotenv'
|
|
22
21
|
spec.add_development_dependency 'pry-byebug'
|
|
23
22
|
spec.add_development_dependency 'rake'
|
|
@@ -4,7 +4,7 @@ require 'active_job'
|
|
|
4
4
|
RSpec.describe Shoryuken::EnvironmentLoader do
|
|
5
5
|
subject { described_class.new({}) }
|
|
6
6
|
|
|
7
|
-
describe '#parse_queues' do
|
|
7
|
+
describe '#parse_queues loads default queues' do
|
|
8
8
|
before do
|
|
9
9
|
allow(subject).to receive(:load_rails)
|
|
10
10
|
allow(subject).to receive(:prefix_active_job_queue_names)
|
|
@@ -22,6 +22,29 @@ RSpec.describe Shoryuken::EnvironmentLoader do
|
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
+
describe '#parse_queues includes delay per groups' do
|
|
26
|
+
before do
|
|
27
|
+
allow(subject).to receive(:load_rails)
|
|
28
|
+
allow(subject).to receive(:prefix_active_job_queue_names)
|
|
29
|
+
allow(subject).to receive(:require_workers)
|
|
30
|
+
allow(subject).to receive(:validate_queues)
|
|
31
|
+
allow(subject).to receive(:validate_workers)
|
|
32
|
+
allow(subject).to receive(:patch_deprecated_workers)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
specify do
|
|
36
|
+
Shoryuken.options[:queues] = ['queue1', 'queue2'] # default queues
|
|
37
|
+
Shoryuken.options[:groups] = [[ 'custom', { queues: ['queue3'], delay: 25 }]]
|
|
38
|
+
subject.load
|
|
39
|
+
|
|
40
|
+
expect(Shoryuken.groups['default'][:queues]).to eq(%w[queue1 queue2])
|
|
41
|
+
expect(Shoryuken.groups['default'][:delay]).to eq(Shoryuken.options[:delay])
|
|
42
|
+
expect(Shoryuken.groups['custom'][:queues]).to eq(%w[queue3])
|
|
43
|
+
expect(Shoryuken.groups['custom'][:delay]).to eq(25)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
25
48
|
describe '#prefix_active_job_queue_names' do
|
|
26
49
|
before do
|
|
27
50
|
allow(subject).to receive(:load_rails)
|
|
@@ -103,9 +103,9 @@ RSpec.describe Shoryuken::Fetcher do
|
|
|
103
103
|
|
|
104
104
|
context 'when FIFO' do
|
|
105
105
|
let(:limit) { 10 }
|
|
106
|
-
let(:queue) { instance_double('Shoryuken::Queue', fifo?: true) }
|
|
106
|
+
let(:queue) { instance_double('Shoryuken::Queue', fifo?: true, name: queue_name) }
|
|
107
107
|
|
|
108
|
-
it 'polls one message at
|
|
108
|
+
it 'polls one message at a time' do
|
|
109
109
|
# see https://github.com/phstc/shoryuken/pull/530
|
|
110
110
|
|
|
111
111
|
allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
|
@@ -115,6 +115,21 @@ RSpec.describe Shoryuken::Fetcher do
|
|
|
115
115
|
|
|
116
116
|
subject.fetch(queue_config, limit)
|
|
117
117
|
end
|
|
118
|
+
|
|
119
|
+
context 'with batch=true' do
|
|
120
|
+
it 'polls the provided limit' do
|
|
121
|
+
# see https://github.com/phstc/shoryuken/pull/530
|
|
122
|
+
|
|
123
|
+
allow(Shoryuken::Client).to receive(:queues).with(queue_name).and_return(queue)
|
|
124
|
+
allow(Shoryuken.worker_registry).to receive(:batch_receive_messages?).with(queue.name).and_return(true)
|
|
125
|
+
|
|
126
|
+
expect(queue).to receive(:receive_messages).with(
|
|
127
|
+
max_number_of_messages: limit, attribute_names: ['All'], message_attribute_names: ['All']
|
|
128
|
+
).and_return([])
|
|
129
|
+
|
|
130
|
+
subject.fetch(queue_config, limit)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
118
133
|
end
|
|
119
134
|
end
|
|
120
135
|
end
|
|
@@ -72,11 +72,27 @@ RSpec.describe Shoryuken::Manager do
|
|
|
72
72
|
expect(fetcher).to receive(:fetch).with(q, concurrency).and_return(messages)
|
|
73
73
|
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
74
74
|
expect(Shoryuken::Processor).to receive(:process).with(q, message)
|
|
75
|
-
expect(Shoryuken.logger).
|
|
75
|
+
expect(Shoryuken.logger).to receive(:info).never
|
|
76
76
|
|
|
77
77
|
subject.send(:dispatch)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
|
+
context 'and there are no messages in the queue' do
|
|
81
|
+
specify do
|
|
82
|
+
messages = %w[]
|
|
83
|
+
q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
|
|
84
|
+
|
|
85
|
+
expect(fetcher).to receive(:fetch).with(q, concurrency).and_return(messages)
|
|
86
|
+
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
87
|
+
expect(polling_strategy).to receive(:messages_found).with(q.name, 0)
|
|
88
|
+
expect(Shoryuken.logger).to receive(:info).never
|
|
89
|
+
expect(Shoryuken::Processor).to receive(:process).never
|
|
90
|
+
expect_any_instance_of(described_class).to receive(:assign).never
|
|
91
|
+
|
|
92
|
+
subject.send(:dispatch)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
80
96
|
context 'when batch' do
|
|
81
97
|
specify do
|
|
82
98
|
messages = %w[test1 test2 test3]
|
|
@@ -86,10 +102,27 @@ RSpec.describe Shoryuken::Manager do
|
|
|
86
102
|
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
87
103
|
allow(subject).to receive(:batched_queue?).with(q).and_return(true)
|
|
88
104
|
expect(Shoryuken::Processor).to receive(:process).with(q, messages)
|
|
89
|
-
expect(Shoryuken.logger).
|
|
105
|
+
expect(Shoryuken.logger).to receive(:info).never
|
|
90
106
|
|
|
91
107
|
subject.send(:dispatch)
|
|
92
108
|
end
|
|
109
|
+
|
|
110
|
+
context 'and there are no messages in the queue' do
|
|
111
|
+
specify do
|
|
112
|
+
messages = %w[]
|
|
113
|
+
q = Shoryuken::Polling::QueueConfiguration.new(queue, {})
|
|
114
|
+
|
|
115
|
+
expect(fetcher).to receive(:fetch).with(q, described_class::BATCH_LIMIT).and_return(messages)
|
|
116
|
+
expect(subject).to receive(:fire_event).with(:dispatch, false, queue_name: q.name)
|
|
117
|
+
allow(subject).to receive(:batched_queue?).with(q).and_return(true)
|
|
118
|
+
expect(polling_strategy).to receive(:messages_found).with(q.name, 0)
|
|
119
|
+
expect(Shoryuken.logger).to receive(:info).never
|
|
120
|
+
expect(Shoryuken::Processor).to receive(:process).never
|
|
121
|
+
expect_any_instance_of(described_class).to receive(:assign).never
|
|
122
|
+
|
|
123
|
+
subject.send(:dispatch)
|
|
124
|
+
end
|
|
125
|
+
end
|
|
93
126
|
end
|
|
94
127
|
end
|
|
95
128
|
|
|
@@ -53,7 +53,7 @@ RSpec.describe Shoryuken::Middleware::Server::AutoExtendVisibility do
|
|
|
53
53
|
allow(sqs_msg).to receive(:queue) { sqs_queue }
|
|
54
54
|
expect(sqs_msg).to_not receive(:change_visibility)
|
|
55
55
|
|
|
56
|
-
expect { Runner.new.run_and_raise(TestWorker.new, queue, sqs_msg) }.to raise_error
|
|
56
|
+
expect { Runner.new.run_and_raise(TestWorker.new, queue, sqs_msg) }.to raise_error(RuntimeError)
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
it 'does not extend message visibility if auto_visibility_timeout is not true' do
|
|
@@ -1,19 +1,37 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
RSpec.describe Shoryuken::Options do
|
|
4
|
-
|
|
4
|
+
subject { Shoryuken.shoryuken_options }
|
|
5
|
+
|
|
6
|
+
describe '.add_group adds queues and optional delay' do
|
|
5
7
|
before do
|
|
6
8
|
Shoryuken.groups.clear
|
|
7
9
|
Shoryuken.add_group('group1', 25)
|
|
8
10
|
Shoryuken.add_group('group2', 25)
|
|
11
|
+
Shoryuken.add_group('group3', 25, delay: 5)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
specify do
|
|
15
|
+
subject.add_queue('queue1', 1, 'group1')
|
|
16
|
+
subject.add_queue('queue2', 2, 'group2')
|
|
17
|
+
subject.add_queue('queue3', 1, 'group3')
|
|
18
|
+
|
|
19
|
+
expect(subject.groups['group1'][:queues]).to eq(%w[queue1])
|
|
20
|
+
expect(subject.groups['group2'][:queues]).to eq(%w[queue2 queue2])
|
|
21
|
+
expect(subject.groups['group3'][:queues]).to eq(%w[queue3])
|
|
22
|
+
expect(subject.groups['group3'][:delay]).to eq(5)
|
|
9
23
|
end
|
|
24
|
+
end
|
|
10
25
|
|
|
26
|
+
describe '.delay works for each group' do
|
|
11
27
|
specify do
|
|
12
|
-
|
|
13
|
-
|
|
28
|
+
Shoryuken.add_group('group1', 25)
|
|
29
|
+
Shoryuken.add_group('group2', 25, delay: 5)
|
|
30
|
+
subject.add_queue('queue1', 1, 'group1')
|
|
31
|
+
subject.add_queue('queue2', 2, 'group2')
|
|
14
32
|
|
|
15
|
-
expect(
|
|
16
|
-
expect(
|
|
33
|
+
expect(subject.delay('group1')).to eq(Shoryuken.options[:delay])
|
|
34
|
+
expect(subject.delay('group2')).to eq(5.0)
|
|
17
35
|
end
|
|
18
36
|
end
|
|
19
37
|
|
|
@@ -25,10 +43,10 @@ RSpec.describe Shoryuken::Options do
|
|
|
25
43
|
end
|
|
26
44
|
|
|
27
45
|
specify do
|
|
28
|
-
|
|
29
|
-
|
|
46
|
+
subject.add_queue('queue1', 1, 'group1')
|
|
47
|
+
subject.add_queue('queue2', 2, 'group2')
|
|
30
48
|
|
|
31
|
-
expect(
|
|
49
|
+
expect(subject.ungrouped_queues).to eq(%w[queue1 queue2 queue2])
|
|
32
50
|
end
|
|
33
51
|
end
|
|
34
52
|
|
|
@@ -52,22 +70,22 @@ RSpec.describe Shoryuken::Options do
|
|
|
52
70
|
|
|
53
71
|
describe '.register_worker' do
|
|
54
72
|
it 'registers a worker' do
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
expect(
|
|
73
|
+
subject.worker_registry.clear
|
|
74
|
+
subject.register_worker('default', TestWorker)
|
|
75
|
+
expect(subject.worker_registry.workers('default')).to eq([TestWorker])
|
|
58
76
|
end
|
|
59
77
|
|
|
60
78
|
it 'registers a batchable worker' do
|
|
61
|
-
|
|
79
|
+
subject.worker_registry.clear
|
|
62
80
|
TestWorker.get_shoryuken_options['batch'] = true
|
|
63
|
-
|
|
64
|
-
expect(
|
|
81
|
+
subject.register_worker('default', TestWorker)
|
|
82
|
+
expect(subject.worker_registry.workers('default')).to eq([TestWorker])
|
|
65
83
|
end
|
|
66
84
|
|
|
67
85
|
it 'allows multiple workers' do
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
expect(
|
|
86
|
+
subject.worker_registry.clear
|
|
87
|
+
subject.register_worker('default', TestWorker)
|
|
88
|
+
expect(subject.worker_registry.workers('default')).to eq([TestWorker])
|
|
71
89
|
|
|
72
90
|
class Test2Worker
|
|
73
91
|
include Shoryuken::Worker
|
|
@@ -77,13 +95,13 @@ RSpec.describe Shoryuken::Options do
|
|
|
77
95
|
def perform(sqs_msg, body); end
|
|
78
96
|
end
|
|
79
97
|
|
|
80
|
-
expect(
|
|
98
|
+
expect(subject.worker_registry.workers('default')).to eq([Test2Worker])
|
|
81
99
|
end
|
|
82
100
|
|
|
83
101
|
it 'raises an exception when mixing batchable with non batchable' do
|
|
84
|
-
|
|
102
|
+
subject.worker_registry.clear
|
|
85
103
|
TestWorker.get_shoryuken_options['batch'] = true
|
|
86
|
-
|
|
104
|
+
subject.register_worker('default', TestWorker)
|
|
87
105
|
|
|
88
106
|
expect {
|
|
89
107
|
class BatchableWorker
|
|
@@ -86,6 +86,14 @@ RSpec.describe Shoryuken::Polling::StrictPriority do
|
|
|
86
86
|
end
|
|
87
87
|
end
|
|
88
88
|
|
|
89
|
+
describe '#delay' do
|
|
90
|
+
it 'sets delay based on group' do
|
|
91
|
+
delay_polling = Shoryuken::Polling::StrictPriority.new(queues, 25)
|
|
92
|
+
expect(delay_polling.delay).to eq(25.0)
|
|
93
|
+
expect(subject.delay).to eq(1.0)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
89
97
|
describe '#messages_found' do
|
|
90
98
|
it 'pauses a queue if there are no messages found' do
|
|
91
99
|
# [shoryuken, 2]
|
|
@@ -96,4 +96,12 @@ RSpec.describe Shoryuken::Polling::WeightedRoundRobin do
|
|
|
96
96
|
expect(subject.instance_variable_get(:@queues)).to eq([queue1, queue2, queue1])
|
|
97
97
|
end
|
|
98
98
|
end
|
|
99
|
+
|
|
100
|
+
describe '#delay' do
|
|
101
|
+
it 'sets delay based on group' do
|
|
102
|
+
delay_polling = Shoryuken::Polling::WeightedRoundRobin.new(queues, 25)
|
|
103
|
+
expect(delay_polling.delay).to eq(25.0)
|
|
104
|
+
expect(subject.delay).to eq(1.0)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
99
107
|
end
|
|
@@ -57,8 +57,8 @@ RSpec.describe Shoryuken::Processor do
|
|
|
57
57
|
|
|
58
58
|
context 'server' do
|
|
59
59
|
before do
|
|
60
|
-
|
|
61
|
-
WorkerCalledMiddlewareWorker.instance_variable_set(:@
|
|
60
|
+
allow_any_instance_of(Shoryuken::Options).to receive(:server?).and_return(true)
|
|
61
|
+
WorkerCalledMiddlewareWorker.instance_variable_set(:@_server_chain, nil) # un-memoize middleware
|
|
62
62
|
|
|
63
63
|
Shoryuken.configure_server do |config|
|
|
64
64
|
config.server_middleware do |chain|
|
|
@@ -85,8 +85,8 @@ RSpec.describe Shoryuken::Processor do
|
|
|
85
85
|
|
|
86
86
|
context 'client' do
|
|
87
87
|
before do
|
|
88
|
-
|
|
89
|
-
WorkerCalledMiddlewareWorker.instance_variable_set(:@
|
|
88
|
+
allow_any_instance_of(Shoryuken::Options).to receive(:server?).and_return(false)
|
|
89
|
+
WorkerCalledMiddlewareWorker.instance_variable_set(:@_server_chain, nil) # un-memoize middleware
|
|
90
90
|
|
|
91
91
|
Shoryuken.configure_server do |config|
|
|
92
92
|
config.server_middleware do |chain|
|
|
@@ -26,6 +26,19 @@ RSpec.describe Shoryuken::Queue do
|
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
context 'when a non SQS queue URL' do
|
|
30
|
+
let(:queue_url) { "http://localhost:4576/queue/#{queue_name}" }
|
|
31
|
+
|
|
32
|
+
it 'instantiates by URL and validate the URL' do
|
|
33
|
+
# See https://github.com/phstc/shoryuken/pull/551
|
|
34
|
+
expect_any_instance_of(described_class).to receive(:fifo?).and_return(false)
|
|
35
|
+
|
|
36
|
+
subject = described_class.new(sqs, queue_url)
|
|
37
|
+
|
|
38
|
+
expect(subject.name).to eq(queue_name)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
29
42
|
context 'when queue name supplied' do
|
|
30
43
|
subject { described_class.new(sqs, queue_name) }
|
|
31
44
|
|
|
@@ -235,7 +248,7 @@ RSpec.describe Shoryuken::Queue do
|
|
|
235
248
|
end
|
|
236
249
|
end
|
|
237
250
|
|
|
238
|
-
describe '#
|
|
251
|
+
describe '#visibility_timeout' do
|
|
239
252
|
let(:attribute_response) { double 'Aws::SQS::Types::GetQueueAttributesResponse' }
|
|
240
253
|
|
|
241
254
|
before do
|
|
@@ -247,7 +260,7 @@ RSpec.describe Shoryuken::Queue do
|
|
|
247
260
|
|
|
248
261
|
context 'when cache is disabled' do
|
|
249
262
|
specify do
|
|
250
|
-
Shoryuken.
|
|
263
|
+
Shoryuken.cache_visibility_timeout = false
|
|
251
264
|
|
|
252
265
|
expect(sqs).to(
|
|
253
266
|
receive(:get_queue_attributes).with(queue_url: queue_url, attribute_names: ['All']).and_return(attribute_response).exactly(3).times
|
|
@@ -260,7 +273,7 @@ RSpec.describe Shoryuken::Queue do
|
|
|
260
273
|
|
|
261
274
|
context 'when cache is enabled' do
|
|
262
275
|
it 'memoizes response' do
|
|
263
|
-
Shoryuken.
|
|
276
|
+
Shoryuken.cache_visibility_timeout = true
|
|
264
277
|
|
|
265
278
|
expect(sqs).to(
|
|
266
279
|
receive(:get_queue_attributes).with(queue_url: queue_url, attribute_names: ['All']).and_return(attribute_response).once
|
data/spec/spec_helper.rb
CHANGED
|
@@ -43,7 +43,7 @@ RSpec.configure do |config|
|
|
|
43
43
|
Shoryuken.groups.clear
|
|
44
44
|
|
|
45
45
|
Shoryuken.options[:concurrency] = 1
|
|
46
|
-
Shoryuken.options[:delay] = 1
|
|
46
|
+
Shoryuken.options[:delay] = 1.0
|
|
47
47
|
Shoryuken.options[:timeout] = 1
|
|
48
48
|
Shoryuken.options[:daemon] = nil
|
|
49
49
|
Shoryuken.options[:logfile] = nil
|
|
@@ -61,7 +61,7 @@ RSpec.configure do |config|
|
|
|
61
61
|
|
|
62
62
|
Shoryuken.sqs_client_receive_message_opts.clear
|
|
63
63
|
|
|
64
|
-
Shoryuken.
|
|
64
|
+
Shoryuken.cache_visibility_timeout = false
|
|
65
65
|
|
|
66
66
|
allow(Concurrent).to receive(:global_io_executor).and_return(Concurrent::ImmediateExecutor.new)
|
|
67
67
|
allow(Shoryuken).to receive(:active_job?).and_return(false)
|
metadata
CHANGED
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shoryuken
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 5.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pablo Cantero
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-06-18 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: bundler
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '1.6'
|
|
20
|
-
type: :development
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '1.6'
|
|
27
13
|
- !ruby/object:Gem::Dependency
|
|
28
14
|
name: dotenv
|
|
29
15
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -228,7 +214,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
228
214
|
version: '0'
|
|
229
215
|
requirements: []
|
|
230
216
|
rubyforge_project:
|
|
231
|
-
rubygems_version: 2.
|
|
217
|
+
rubygems_version: 2.7.6.2
|
|
232
218
|
signing_key:
|
|
233
219
|
specification_version: 4
|
|
234
220
|
summary: Shoryuken is a super efficient AWS SQS thread based message processor
|