shoryuken 3.0.7 → 3.1.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.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -0
  4. data/CHANGELOG.md +53 -0
  5. data/Gemfile +1 -0
  6. data/README.md +15 -110
  7. data/bin/cli/sqs.rb +18 -1
  8. data/examples/default_worker.rb +1 -1
  9. data/lib/shoryuken/default_worker_registry.rb +2 -2
  10. data/lib/shoryuken/environment_loader.rb +33 -13
  11. data/lib/shoryuken/fetcher.rb +17 -16
  12. data/lib/shoryuken/launcher.rb +86 -7
  13. data/lib/shoryuken/manager.rb +39 -80
  14. data/lib/shoryuken/middleware/server/auto_delete.rb +3 -8
  15. data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +4 -4
  16. data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +4 -2
  17. data/lib/shoryuken/middleware/server/timing.rb +2 -2
  18. data/lib/shoryuken/options.rb +192 -0
  19. data/lib/shoryuken/polling/base.rb +67 -0
  20. data/lib/shoryuken/polling/strict_priority.rb +77 -0
  21. data/lib/shoryuken/polling/weighted_round_robin.rb +66 -0
  22. data/lib/shoryuken/processor.rb +21 -18
  23. data/lib/shoryuken/queue.rb +27 -6
  24. data/lib/shoryuken/runner.rb +3 -15
  25. data/lib/shoryuken/version.rb +1 -1
  26. data/lib/shoryuken/worker.rb +8 -0
  27. data/lib/shoryuken.rb +39 -173
  28. data/shoryuken.gemspec +1 -1
  29. data/spec/integration/launcher_spec.rb +12 -6
  30. data/spec/shoryuken/environment_loader_spec.rb +3 -12
  31. data/spec/shoryuken/fetcher_spec.rb +30 -15
  32. data/spec/shoryuken/manager_spec.rb +9 -17
  33. data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +1 -1
  34. data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +1 -1
  35. data/spec/shoryuken/options_spec.rb +100 -0
  36. data/spec/shoryuken/{polling_spec.rb → polling/strict_priority_spec.rb} +1 -100
  37. data/spec/shoryuken/polling/weighted_round_robin_spec.rb +99 -0
  38. data/spec/shoryuken/processor_spec.rb +20 -39
  39. data/spec/shoryuken/queue_spec.rb +72 -26
  40. data/spec/shoryuken/runner_spec.rb +3 -4
  41. data/spec/shoryuken_spec.rb +0 -59
  42. data/spec/spec_helper.rb +8 -2
  43. data/test_workers/endless_uninterruptive_worker.rb +1 -1
  44. metadata +14 -7
  45. data/lib/shoryuken/polling.rb +0 -204
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3d0347fa63667fbc483984759877ee74a65919cd
4
- data.tar.gz: a06ea715ee035e398cdab792c2647b3e6575f216
3
+ metadata.gz: 779c3e9c7f708f0a6dccb3e8b0c9f7e2490b25e1
4
+ data.tar.gz: bf260a2793ff8c07ddfb670832ba5f12af8d85d9
5
5
  SHA512:
6
- metadata.gz: 4a560a9dbc3f31706263ac0f3d15a90b976e7dcc2b040eab0317e0ceb782ea239cea95c8e96d0c6bf0ee7cc4a3d4be30fb2249ddc177c35500a60b463e52beee
7
- data.tar.gz: 94776b105d1288009d3b5d93022a6c0fd95a5981daa13925c0453802d90e6215e0d37eb5b044af8ce267559b9becdc49921e9842e6b34b672cb892762f6e4615
6
+ metadata.gz: 1f3e7a4b668c929daa1b5424b7a8ab7f028238b3f6dfe0e812351991bbc37923b58491760df6e4ed4921624cd4954761daeac257c6a540fd193d160d121044de
7
+ data.tar.gz: 02f2bf2e813cbe1624ae83d16936196ecf523fe8d3773f9b0c39813aa0822d3c71fd273ee01a63072c20d86bf05f4c1a775eda3fae41cec4bf55ea567f772aef
data/.rubocop.yml CHANGED
@@ -32,7 +32,7 @@ Metrics/ParameterLists:
32
32
  Enabled: false
33
33
 
34
34
  Metrics/LineLength:
35
- Max: 120
35
+ Max: 130
36
36
 
37
37
  Metrics/MethodLength :
38
38
  Enabled: false
data/.travis.yml CHANGED
@@ -4,6 +4,7 @@ rvm:
4
4
  - 2.1.0
5
5
  - 2.2.0
6
6
  - 2.3.3
7
+ - 2.4.1
7
8
 
8
9
  notifications:
9
10
  email:
data/CHANGELOG.md CHANGED
@@ -1,4 +1,45 @@
1
+ ## [v3.1.0] - 2017-07-02
2
+
3
+ - Add shoryuken sqs delete command
4
+ - [#395](https://github.com/phstc/shoryuken/pull/395)
5
+
6
+ - Add processing groups support; Concurrency per queue support
7
+ - [#389](https://github.com/phstc/shoryuken/pull/389)
8
+
9
+ - Terminate Shoryuken if the fetcher crashes
10
+ - [#389](https://github.com/phstc/shoryuken/pull/389)
11
+
12
+ ## [v3.0.11] - 2017-06-24
13
+
14
+ - Add shoryuken sqs create command
15
+ - [#388](https://github.com/phstc/shoryuken/pull/388)
16
+
17
+ ## [v3.0.10] - 2017-06-24
18
+
19
+ - Allow aws sdk v3
20
+ - [#381](https://github.com/phstc/shoryuken/pull/381)
21
+
22
+ - Allow configuring Rails via the config file
23
+ - [#387](https://github.com/phstc/shoryuken/pull/387)
24
+
25
+ ## [v3.0.9] - 2017-06-05
26
+
27
+ - Allow configuring queue URLs instead of names
28
+ - [#378](https://github.com/phstc/shoryuken/pull/378)
29
+
30
+ ## [v3.0.8] - 2017-06-02
31
+
32
+ - Fix miss handling empty batch fetches
33
+ - [#376](https://github.com/phstc/shoryuken/pull/376)
34
+
35
+ - Various minor styling changes :lipstick:
36
+ - [#373](https://github.com/phstc/shoryuken/pull/373)
37
+
38
+ - Logout when batch delete returns any failure
39
+ - [#371](https://github.com/phstc/shoryuken/pull/371)
40
+
1
41
  ## [v3.0.7] - 2017-05-18
42
+
2
43
  - Trigger events for dispatch
3
44
  - [#362](https://github.com/phstc/shoryuken/pull/362)
4
45
 
@@ -9,10 +50,12 @@
9
50
  - [#366](https://github.com/phstc/shoryuken/pull/366)
10
51
 
11
52
  ## [v3.0.6] - 2017-04-11
53
+
12
54
  - Fix delay option type
13
55
  - [#356](https://github.com/phstc/shoryuken/pull/356)
14
56
 
15
57
  ## [v3.0.5] - 2017-04-09
58
+
16
59
  - Pause endless dispatcher to avoid CPU overload
17
60
  - [#354](https://github.com/phstc/shoryuken/pull/354)
18
61
 
@@ -24,7 +67,9 @@
24
67
 
25
68
  - Add `sqs purge` command. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_PurgeQueue.html
26
69
  - [#344](https://github.com/phstc/shoryuken/pull/344)
70
+
27
71
  ## [v3.0.4] - 2017-03-24
72
+
28
73
  - Add `sqs purge` command. See https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_PurgeQueue.html
29
74
  - [#344](https://github.com/phstc/shoryuken/pull/344)
30
75
 
@@ -32,18 +77,22 @@
32
77
  - [#345](https://github.com/phstc/shoryuken/pull/345)
33
78
 
34
79
  ## [v3.0.3] - 2017-03-19
80
+
35
81
  - Update `sqs` CLI commands to use `get_queue_url` when appropriated
36
82
  - [#341](https://github.com/phstc/shoryuken/pull/341)
37
83
 
38
84
  ## [v3.0.2] - 2017-03-19
85
+
39
86
  - Fix custom SQS client initialization
40
87
  - [#335](https://github.com/phstc/shoryuken/pull/335)
41
88
 
42
89
  ## [v3.0.1] - 2017-03-13
90
+
43
91
  - Fix commands sqs mv and dump `options.delete` checker
44
92
  - [#332](https://github.com/phstc/shoryuken/pull/332)
45
93
 
46
94
  ## [v3.0.0] - 2017-03-12
95
+
47
96
  - Replace Celluloid with Concurrent Ruby
48
97
  - [#291](https://github.com/phstc/shoryuken/pull/291)
49
98
 
@@ -63,6 +112,7 @@
63
112
  - [#330](https://github.com/phstc/shoryuken/pull/330)
64
113
 
65
114
  ## [v2.1.3] - 2017-01-27
115
+
66
116
  - Show a warn message when batch isn't supported
67
117
  - [#302](https://github.com/phstc/shoryuken/pull/302)
68
118
 
@@ -73,6 +123,7 @@
73
123
  - [#307](https://github.com/phstc/shoryuken/pull/307)
74
124
 
75
125
  ## [v2.1.2] - 2016-12-22
126
+
76
127
  - Fix loading `logfile` from shoryuken.yml
77
128
  - [#296](https://github.com/phstc/shoryuken/pull/296)
78
129
 
@@ -92,10 +143,12 @@
92
143
  - [#284](https://github.com/phstc/shoryuken/pull/284)
93
144
 
94
145
  ## [v2.1.1] - 2016-12-05
146
+
95
147
  - Fix aws deprecation warning message
96
148
  - [#279](https://github.com/phstc/shoryuken/pull/279)
97
149
 
98
150
  ## [v2.1.0] - 2016-12-03
151
+
99
152
  - Fix celluloid "running in BACKPORTED mode" warning
100
153
  - [#260](https://github.com/phstc/shoryuken/pull/260)
101
154
 
data/Gemfile CHANGED
@@ -7,4 +7,5 @@ group :test do
7
7
  gem 'codeclimate-test-reporter', require: nil
8
8
  gem 'simplecov'
9
9
  gem 'multi_xml'
10
+ gem 'httparty'
10
11
  end
data/README.md CHANGED
@@ -1,35 +1,23 @@
1
1
  # Shoryuken
2
2
 
3
- ![](shoryuken.jpg)
3
+ ![Shoryuken](shoryuken.jpg)
4
4
 
5
- Shoryuken _sho-ryu-ken_ is a super-efficient [AWS SQS](https://aws.amazon.com/sqs/) thread-based message processor.
5
+ Shoryuken _sho-ryu-ken_ is a super-efficient [Amazon SQS](https://aws.amazon.com/sqs/) thread-based message processor.
6
6
 
7
7
  [![Build Status](https://travis-ci.org/phstc/shoryuken.svg)](https://travis-ci.org/phstc/shoryuken)
8
8
  [![Code Climate](https://codeclimate.com/github/phstc/shoryuken/badges/gpa.svg)](https://codeclimate.com/github/phstc/shoryuken)
9
9
 
10
10
  ## Key features
11
11
 
12
- ### Load balancing
13
-
14
- Yeah, Shoryuken load balances the messages consumption!
15
-
16
- ```yaml
17
- concurrency: 25
18
- delay: 0
19
- queues:
20
- - [high_priority, 6]
21
- - [normal_priority, 2]
22
- - [low_priority, 1]
23
- ```
24
-
25
- Or you can set them all to 1 for having the same priorities.
26
-
27
- - `concurrency` (default 25) is the number of threads you want to make available for processing.
28
- - `delay` (default to 0) is the number of seconds to pause fetching from an empty queue. SQS charges per request, pause checking empty queues for a while can be a cost efficient strategy.
29
-
30
- ### Fetch in batches
31
-
32
- To be even more performant and cost effective, Shoryuken fetches SQS messages in batches, so a single SQS request can fetch up to 10 messages.
12
+ - [Rails Active Job](https://github.com/phstc/shoryuken/wiki/Rails-Integration-Active-Job)
13
+ - [Queue Load balancing](https://github.com/phstc/shoryuken/wiki/Shoryuken-options#load-balancing)
14
+ - [Concurrency per queue](https://github.com/phstc/shoryuken/wiki/Processing-Groups)
15
+ - [Long Polling](https://github.com/phstc/shoryuken/wiki/Long-Polling)
16
+ - [Batch processing](https://github.com/phstc/shoryuken/wiki/Worker-options#batch)
17
+ - [Auto extend visibility timeout](https://github.com/phstc/shoryuken/wiki/Worker-options#auto_visibility_timeout)
18
+ - [Exponential backoff](https://github.com/phstc/shoryuken/wiki/Worker-options#retry_intervals)
19
+ - [Middleware support](https://github.com/phstc/shoryuken/wiki/Middleware)
20
+ - Amazon SQS CLI. See `shoryuken help sqs`
33
21
 
34
22
  ## Requirements
35
23
 
@@ -43,102 +31,19 @@ Add this line to your application's Gemfile:
43
31
  gem 'shoryuken'
44
32
  ```
45
33
 
46
- Or to get the latest updates:
47
-
48
- ```ruby
49
- gem 'shoryuken', github: 'phstc/shoryuken', branch: 'master'
50
- ```
51
-
52
34
  And then execute:
53
35
 
54
- $ bundle
55
-
56
- Or install it yourself as:
57
-
58
- $ gem install shoryuken
59
-
60
- ## Usage
61
-
62
- ### Worker class
63
-
64
- ```ruby
65
- class MyWorker
66
- include Shoryuken::Worker
67
-
68
- shoryuken_options queue: 'default', auto_delete: true
69
- # shoryuken_options queue: ->{ "#{ENV['environment']}_default" }
70
-
71
- # shoryuken_options body_parser: :json
72
- # shoryuken_options body_parser: ->(sqs_msg){ REXML::Document.new(sqs_msg.body) }
73
- # shoryuken_options body_parser: JSON
74
-
75
- def perform(sqs_msg, body)
76
- puts body
77
- end
78
- end
79
- ```
80
-
81
- [Check the Worker options documention](https://github.com/phstc/shoryuken/wiki/Worker-options).
82
-
83
- ### Sending a message
84
-
85
- [Check the Sending a message documentation](https://github.com/phstc/shoryuken/wiki/Sending-a-message)
86
-
87
- ### Middleware
88
-
89
- ```ruby
90
- class MyMiddleware
91
- def call(worker_instance, queue, sqs_msg, body)
92
- puts 'Before work'
93
- yield
94
- puts 'After work'
95
- end
96
- end
97
- ```
98
-
99
- [Check the Middleware documentation](https://github.com/phstc/shoryuken/wiki/Middleware).
100
-
101
- ### Shoryuken Configuration
102
-
103
- Sample configuration file `shoryuken.yml`.
104
-
105
- ```yaml
106
- concurrency: 25 # The number of allocated threads to process messages. Default 25
107
- delay: 0 # The delay in seconds to pause empty queues. Default 0
108
- queues:
109
- - [queue1, 1]
110
- - [queue2, 1]
111
- - [queue3, 1]
112
- ```
113
-
114
- #### AWS Configuration
115
-
116
- [Check the Configure AWS Client documentation](https://github.com/phstc/shoryuken/wiki/Configure-the-AWS-Client)
117
-
118
- ### Rails Integration
119
-
120
- [Check the Rails Integration Active Job documention](https://github.com/phstc/shoryuken/wiki/Rails-Integration-Active-Job).
121
-
122
- ### Start Shoryuken
123
-
124
36
  ```shell
125
- bundle exec shoryuken -r worker.rb -C shoryuken.yml
37
+ $ bundle
126
38
  ```
127
39
 
128
- For other options check `bundle exec shoryuken help start`
129
-
130
- #### SQS commands
131
-
132
- Check also some available SQS commands `bundle exec shoryuken help sqs`, such as:
40
+ ## Usage
133
41
 
134
- - `ls` list queues
135
- - `mv` move messages from one queue to another
136
- - `dump` dump messages from a queue into a JSON lines file
137
- - `requeue` requeue messages from a dump file
42
+ Check the [Getting Started](https://github.com/phstc/shoryuken/wiki/Getting-Started) page.
138
43
 
139
44
  ## More Information
140
45
 
141
- For more information on advanced topics such as signals (shutdown), ActiveJob integration, and so on please check the [Shoryuken Wiki](https://github.com/phstc/shoryuken/wiki).
46
+ For more information check the [wiki page](https://github.com/phstc/shoryuken/wiki).
142
47
 
143
48
  ## Credits
144
49
 
data/bin/cli/sqs.rb CHANGED
@@ -32,7 +32,10 @@ module Shoryuken
32
32
  queue_url: url,
33
33
  entries: batch.map { |message| { id: message.message_id, receipt_handle: message.receipt_handle } }
34
34
  ).failed.any? do |failure|
35
- say "Could not delete #{failure.id}, code: #{failure.code}", :yellow
35
+ say(
36
+ "Could not delete #{failure.id}, code: #{failure.code}, message: #{failure.message}, sender_fault: #{failure.sender_fault}",
37
+ :yellow
38
+ )
36
39
  end
37
40
  end
38
41
  end
@@ -182,6 +185,20 @@ module Shoryuken
182
185
 
183
186
  say "Purge request sent for #{queue_name}. The message deletion process takes up to 60 seconds", :yellow
184
187
  end
188
+
189
+ desc 'create QUEUE-NAME', 'Create a queue'
190
+ def create(queue_name)
191
+ queue_url = sqs.create_queue(queue_name: queue_name).queue_url
192
+
193
+ say "Queue #{queue_name} was successfully created. Queue URL #{queue_url}", :green
194
+ end
195
+
196
+ desc 'delete QUEUE-NAME', 'delete a queue'
197
+ def delete(queue_name)
198
+ sqs.delete_queue(queue_url: find_queue_url(queue_name))
199
+
200
+ say "Queue #{queue_name} was successfully delete", :green
201
+ end
185
202
  end
186
203
  end
187
204
  end
@@ -4,6 +4,6 @@ class DefaultWorker
4
4
  shoryuken_options queue: 'default', auto_delete: true
5
5
 
6
6
  def perform(sqs_msg, body)
7
- Shoryuken.logger.debug("Received message: '#{body}'")
7
+ Shoryuken.logger.debug("Received message: #{body}")
8
8
  end
9
9
  end
@@ -24,7 +24,7 @@ module Shoryuken
24
24
  @workers[queue]
25
25
  end
26
26
 
27
- worker_class.new
27
+ worker_class.new if worker_class
28
28
  end
29
29
 
30
30
  def queues
@@ -34,7 +34,7 @@ module Shoryuken
34
34
  def register_worker(queue, clazz)
35
35
  if (worker_class = @workers[queue])
36
36
  if worker_class.get_shoryuken_options['batch'] == true || clazz.get_shoryuken_options['batch'] == true
37
- fail ArgumentError, "Could not register #{clazz} for '#{queue}', "\
37
+ fail ArgumentError, "Could not register #{clazz} for #{queue}, "\
38
38
  "because #{worker_class} is already registered for this queue, "\
39
39
  "and Shoryuken doesn't support a batchable worker for a queue with multiple workers"
40
40
  end
@@ -24,7 +24,7 @@ module Shoryuken
24
24
  end
25
25
 
26
26
  def load
27
- load_rails if options[:rails]
27
+ load_rails if Shoryuken.options[:rails]
28
28
  prefix_active_job_queue_names
29
29
  parse_queues
30
30
  require_workers
@@ -42,9 +42,13 @@ module Shoryuken
42
42
  def config_file_options
43
43
  return {} unless (path = options[:config_file])
44
44
 
45
- fail ArgumentError, "The supplied config file '#{path}' does not exist" unless File.exist?(path)
45
+ fail ArgumentError, "The supplied config file #{path} does not exist" unless File.exist?(path)
46
46
 
47
- YAML.load(ERB.new(IO.read(path)).result).deep_symbolize_keys
47
+ if result = YAML.load(ERB.new(IO.read(path)).result)
48
+ result.deep_symbolize_keys
49
+ else
50
+ {}
51
+ end
48
52
  end
49
53
 
50
54
  def initialize_logger
@@ -96,13 +100,24 @@ module Shoryuken
96
100
  end
97
101
  end
98
102
 
99
- def parse_queue(queue, weight = nil)
100
- Shoryuken.add_queue(queue, [weight.to_i, 1].max)
103
+ def parse_queue(queue, weight = nil, group)
104
+ Shoryuken.add_queue(queue, [weight.to_i, 1].max, group)
101
105
  end
102
106
 
103
107
  def parse_queues
104
- Shoryuken.options[:queues].to_a.each do |queue_and_weight|
105
- parse_queue(*queue_and_weight)
108
+ if Shoryuken.options[:queues].to_a.any?
109
+ Shoryuken.add_group('default', Shoryuken.options.fetch(:concurrency, 25))
110
+
111
+ Shoryuken.options[:queues].to_a.each do |queue, weight|
112
+ parse_queue(queue, weight, 'default')
113
+ end
114
+ end
115
+
116
+ Shoryuken.options[:groups].to_a.each do |group, options|
117
+ Shoryuken.add_group(group, options.fetch(:concurrency, 25))
118
+ options[:queues].to_a.each do |queue, weight|
119
+ parse_queue(queue, weight, group)
120
+ end
106
121
  end
107
122
  end
108
123
 
@@ -119,29 +134,34 @@ module Shoryuken
119
134
  end
120
135
 
121
136
  def validate_queues
122
- Shoryuken.logger.warn { 'No queues supplied' } if Shoryuken.queues.empty?
137
+ return Shoryuken.logger.warn { 'No queues supplied' } if Shoryuken.ungrouped_queues.empty?
123
138
 
124
139
  non_existent_queues = []
125
140
 
126
- Shoryuken.queues.uniq.each do |queue|
141
+ Shoryuken.ungrouped_queues.uniq.each do |queue|
127
142
  begin
128
143
  Shoryuken::Client.queues(queue)
129
- rescue Aws::SQS::Errors::NonExistentQueue
144
+ rescue Aws::Errors::NoSuchEndpointError, Aws::SQS::Errors::NonExistentQueue
130
145
  non_existent_queues << queue
131
146
  end
132
147
  end
133
148
 
134
- fail ArgumentError, "The specified queue(s) #{non_existent_queues} do not exist" if non_existent_queues.any?
149
+ return if non_existent_queues.none?
150
+
151
+ fail(
152
+ ArgumentError,
153
+ "The specified queue(s) #{non_existent_queues.join(', ')} do not exist.\nTry 'shoryuken sqs create QUEUE-NAME' for creating a queue with default settings"
154
+ )
135
155
  end
136
156
 
137
157
  def validate_workers
138
158
  return if defined?(::ActiveJob)
139
159
 
140
- all_queues = Shoryuken.queues
160
+ all_queues = Shoryuken.ungrouped_queues
141
161
  queues_with_workers = Shoryuken.worker_registry.queues
142
162
 
143
163
  (all_queues - queues_with_workers).each do |queue|
144
- Shoryuken.logger.warn { "No worker supplied for '#{queue}'" }
164
+ Shoryuken.logger.warn { "No worker supplied for #{queue}" }
145
165
  end
146
166
  end
147
167
  end
@@ -4,23 +4,23 @@ module Shoryuken
4
4
 
5
5
  FETCH_LIMIT = 10
6
6
 
7
- def fetch(queue, available_processors)
7
+ attr_reader :group
8
+
9
+ def initialize(group)
10
+ @group = group
11
+ end
12
+
13
+ def fetch(queue, limit)
8
14
  started_at = Time.now
9
15
 
10
- logger.debug { "Looking for new messages in '#{queue}'" }
16
+ logger.debug { "Looking for new messages in #{queue}" }
11
17
 
12
- begin
13
- limit = available_processors > FETCH_LIMIT ? FETCH_LIMIT : available_processors
18
+ sqs_msgs = Array(receive_messages(queue, [FETCH_LIMIT, limit].min))
14
19
 
15
- sqs_msgs = Array(receive_messages(queue, limit))
16
- logger.info { "Found #{sqs_msgs.size} messages for '#{queue.name}'" } unless sqs_msgs.empty?
17
- logger.debug { "Fetcher for '#{queue}' completed in #{elapsed(started_at)} ms" }
18
- sqs_msgs
19
- rescue => ex
20
- logger.error { "Error fetching message: #{ex}" }
21
- logger.error { ex.backtrace.first }
22
- []
23
- end
20
+ logger.info { "Found #{sqs_msgs.size} messages for #{queue.name}" } unless sqs_msgs.empty?
21
+ logger.debug { "Fetcher for #{queue} completed in #{elapsed(started_at)} ms" }
22
+
23
+ sqs_msgs
24
24
  end
25
25
 
26
26
  private
@@ -29,10 +29,11 @@ module Shoryuken
29
29
  # AWS limits the batch size by 10
30
30
  limit = limit > FETCH_LIMIT ? FETCH_LIMIT : limit
31
31
 
32
- options = Shoryuken.sqs_client_receive_message_opts.to_h.dup
33
- options[:max_number_of_messages] = limit
32
+ options = Shoryuken.sqs_client_receive_message_opts[group].to_h.dup
33
+
34
+ options[:max_number_of_messages] = limit
34
35
  options[:message_attribute_names] = %w(All)
35
- options[:attribute_names] = %w(All)
36
+ options[:attribute_names] = %w(All)
36
37
 
37
38
  options.merge!(queue.options)
38
39
 
@@ -3,17 +3,96 @@ module Shoryuken
3
3
  include Util
4
4
 
5
5
  def initialize
6
- @manager = Shoryuken::Manager.new(Shoryuken::Fetcher.new,
7
- Shoryuken.options[:polling_strategy].new(Shoryuken.queues))
6
+ @managers = create_managers
7
+ @shutdowning = Concurrent::AtomicBoolean.new(false)
8
8
  end
9
9
 
10
- def stop(options = {})
11
- @manager.stop(shutdown: !options[:shutdown].nil?,
12
- timeout: Shoryuken.options[:timeout])
10
+ def start
11
+ logger.info { 'Starting' }
12
+
13
+ start_callback
14
+ start_managers
15
+ end
16
+
17
+ def stop!
18
+ initiate_stop
19
+
20
+ executor.shutdown
21
+
22
+ return if executor.wait_for_termination(Shoryuken.options[:timeout])
23
+
24
+ executor.kill
25
+ end
26
+
27
+ def stop
28
+ fire_event(:quiet, true)
29
+
30
+ initiate_stop
31
+
32
+ executor.shutdown
33
+ executor.wait_for_termination
34
+ end
35
+
36
+ private
37
+
38
+ def executor
39
+ Concurrent.global_io_executor
40
+ end
41
+
42
+ def start_managers
43
+ @managers.each do |manager|
44
+ Concurrent::Promise.execute { manager.start }.rescue do |ex|
45
+ log_manager_failure(ex)
46
+ start_soft_shutdown
47
+ end
48
+ end
49
+ end
50
+
51
+ def start_soft_shutdown
52
+ Process.kill('USR1', Process.pid) if @shutdowning.make_true
53
+ end
54
+
55
+ def log_manager_failure(ex)
56
+ return unless ex
57
+
58
+ logger.error { "Manager failed: #{ex.message}" }
59
+ logger.error { ex.backtrace.join("\n") } unless ex.backtrace.nil?
60
+ end
61
+
62
+ def initiate_stop
63
+ logger.info { 'Shutting down' }
64
+
65
+ @managers.each(&:stop)
66
+
67
+ stop_callback
68
+ end
69
+
70
+ def start_callback
71
+ if (callback = Shoryuken.start_callback)
72
+ logger.debug { 'Calling start_callback' }
73
+ callback.call
74
+ end
75
+
76
+ fire_event(:startup)
77
+ end
78
+
79
+ def stop_callback
80
+ if (callback = Shoryuken.stop_callback)
81
+ logger.debug { 'Calling stop_callback' }
82
+ callback.call
83
+ end
84
+
85
+ fire_event(:shutdown, true)
13
86
  end
14
87
 
15
- def run
16
- @manager.start
88
+ def create_managers
89
+ Shoryuken.groups.map do |group, options|
90
+ Shoryuken::Manager.new(
91
+ Shoryuken::Fetcher.new(group),
92
+ Shoryuken.polling_strategy(group).new(options[:queues]),
93
+ options[:concurrency]
94
+ )
95
+ end
17
96
  end
18
97
  end
19
98
  end