shoryuken 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +53 -5
- data/lib/shoryuken.rb +26 -25
- data/lib/shoryuken/cli.rb +22 -17
- data/lib/shoryuken/default_worker_registry.rb +46 -0
- data/lib/shoryuken/extensions/active_job_adapter.rb +63 -0
- data/lib/shoryuken/fetcher.rb +2 -3
- data/lib/shoryuken/launcher.rb +4 -2
- data/lib/shoryuken/manager.rb +26 -13
- data/lib/shoryuken/middleware/chain.rb +4 -0
- data/lib/shoryuken/middleware/server/timing.rb +1 -1
- data/lib/shoryuken/processor.rb +33 -7
- data/lib/shoryuken/util.rb +13 -0
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +19 -1
- data/lib/shoryuken/worker_registry.rb +34 -0
- data/shoryuken.gemspec +2 -2
- data/spec/shoryuken/default_worker_registry_spec.rb +83 -0
- data/spec/shoryuken/manager_spec.rb +6 -0
- data/spec/shoryuken/processor_spec.rb +65 -8
- data/spec/shoryuken/util_spec.rb +10 -0
- data/spec/shoryuken/worker_spec.rb +100 -2
- data/spec/shoryuken_spec.rb +9 -9
- data/spec/spec_helper.rb +1 -1
- metadata +10 -8
- data/lib/shoryuken/worker_loader.rb +0 -17
- data/spec/shoryuken/worker_loader_spec.rb +0 -27
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 93f2193b2c553192ca3d38d1dbcd981bbaa35eeb
|
4
|
+
data.tar.gz: d46dcc643bb7fffeb78f4e2f6ca7f4e1b236d688
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5827e0327eba8f21ab4156d197ea0fd5a8587aa86afda60d14ffc9269e5606aa9688060d59d711821bc117d69ae49a41c0837aaea09433dbb3081fc66b36b9d3
|
7
|
+
data.tar.gz: fcc6b86772574af993cf9145f4d1b0f5bd3e4900937f13c2328ab7dd292dc9bbe1c9e502ea5826220734f091a6ae9d759c0ec1e836c10ce85858925071d94f01
|
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
![](shoryuken.jpg)
|
4
4
|
|
5
|
-
Shoryuken _sho-ryu-ken_ is a super
|
5
|
+
Shoryuken _sho-ryu-ken_ is a super-efficient [AWS 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
|
|
@@ -41,11 +41,15 @@ To be even more performance and cost efficient, Shoryuken fetches SQS messages i
|
|
41
41
|
|
42
42
|
Add this line to your application's Gemfile:
|
43
43
|
|
44
|
-
|
44
|
+
```ruby
|
45
|
+
gem 'shoryuken'
|
46
|
+
```
|
45
47
|
|
46
48
|
Or to get the latest updates:
|
47
49
|
|
48
|
-
|
50
|
+
```ruby
|
51
|
+
gem 'shoryuken', github: 'phstc/shoryuken', branch: 'master'
|
52
|
+
```
|
49
53
|
|
50
54
|
And then execute:
|
51
55
|
|
@@ -64,7 +68,7 @@ class MyWorker
|
|
64
68
|
include Shoryuken::Worker
|
65
69
|
|
66
70
|
shoryuken_options queue: 'default', auto_delete: true
|
67
|
-
# shoryuken_options queue: ->{ "#{ENV['environment']_default" }
|
71
|
+
# shoryuken_options queue: ->{ "#{ENV['environment']}_default" }
|
68
72
|
|
69
73
|
# shoryuken_options body_parser: :json
|
70
74
|
# shoryuken_options body_parser: ->(sqs_msg){ REXML::Document.new(sqs_msg.body) }
|
@@ -82,7 +86,7 @@ end
|
|
82
86
|
|
83
87
|
[Check the Sending a message documentation](https://github.com/phstc/shoryuken/wiki/Sending-a-message)
|
84
88
|
|
85
|
-
###
|
89
|
+
### Middleware
|
86
90
|
|
87
91
|
```ruby
|
88
92
|
class MyMiddleware
|
@@ -124,8 +128,52 @@ You can tell Shoryuken to load your Rails application by passing the `-R` or `--
|
|
124
128
|
|
125
129
|
If you load Rails, and assuming your workers are located in the `app/workers` directory, they will be auto-loaded. This means you don't need to require them explicitly with `-r`.
|
126
130
|
|
131
|
+
For middleware and other configuration, you might want to create an initializer:
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
Shoryuken.configure_server do |config|
|
135
|
+
# Replace Rails logger so messages are logged wherever Shoryuken is logging
|
136
|
+
# Note: this entire block is only run by the processor, so we don't overwrite
|
137
|
+
# the logger when the app is running as usual.
|
138
|
+
Rails.logger = Shoryuken::Logging.logger
|
139
|
+
|
140
|
+
config.server_middleware do |chain|
|
141
|
+
chain.add Shoryuken::MyMiddleware
|
142
|
+
end
|
143
|
+
end
|
144
|
+
```
|
145
|
+
|
146
|
+
*Note:* In the above case, since we are replacing the Rails logger, it's desired that this initializer runs before other initializers (in case they themselves use the logger). Since by Rails conventions initializers are executed in alphabetical order, this can be achieved by prepending the initializer filename with `00_` (assuming no other initializers alphabetically precede this one).
|
147
|
+
|
127
148
|
This feature works for Rails 4+, but needs to be confirmed for older versions.
|
128
149
|
|
150
|
+
#### ActiveJob Support
|
151
|
+
|
152
|
+
Yes, Shoryuken supports ActiveJob! This means that you can put your jobs in processor-agnostic `ActiveJob::Base` subclasses, and change processors whenever you want (or better yet, switch to Shoryuken from another processor easily!).
|
153
|
+
|
154
|
+
It works as expected. Just put your job in `app/jobs`. Here's an example:
|
155
|
+
|
156
|
+
```ruby
|
157
|
+
class ProcessPhotoJob < ActiveJob::Base
|
158
|
+
queue_as :default
|
159
|
+
|
160
|
+
rescue_from ActiveJob::DeserializationError do |e|
|
161
|
+
Shoryuken.logger.error ex
|
162
|
+
Shoryuken.logger.error ex.backtrace.join("\n")
|
163
|
+
end
|
164
|
+
|
165
|
+
def perform(photo)
|
166
|
+
photo.process_image!
|
167
|
+
end
|
168
|
+
end
|
169
|
+
```
|
170
|
+
|
171
|
+
Delayed mailers, ActiveRecord serialization, etc. all work.
|
172
|
+
|
173
|
+
See [ActiveJob docs](http://edgeguides.rubyonrails.org/active_job_basics.html) for more info.
|
174
|
+
|
175
|
+
*Note:* When queueing jobs to be performed in the future (e.g when setting the `wait` or `wait_until` ActiveJob options), SQS limits the amount of time to 15 minutes. Shoryuken will raise an exception if you attempt to schedule a job further into the future than this limit.
|
176
|
+
|
129
177
|
### Start Shoryuken
|
130
178
|
|
131
179
|
```shell
|
data/lib/shoryuken.rb
CHANGED
@@ -7,7 +7,8 @@ require 'shoryuken/core_ext'
|
|
7
7
|
require 'shoryuken/util'
|
8
8
|
require 'shoryuken/client'
|
9
9
|
require 'shoryuken/worker'
|
10
|
-
require 'shoryuken/
|
10
|
+
require 'shoryuken/worker_registry'
|
11
|
+
require 'shoryuken/default_worker_registry'
|
11
12
|
require 'shoryuken/logging'
|
12
13
|
require 'shoryuken/middleware/chain'
|
13
14
|
require 'shoryuken/middleware/server/auto_delete'
|
@@ -22,31 +23,14 @@ module Shoryuken
|
|
22
23
|
timeout: 8
|
23
24
|
}
|
24
25
|
|
25
|
-
@@
|
26
|
-
@@
|
27
|
-
@@worker_loader = WorkerLoader
|
26
|
+
@@queues = []
|
27
|
+
@@worker_registry = DefaultWorkerRegistry.new
|
28
28
|
|
29
29
|
class << self
|
30
30
|
def options
|
31
31
|
@options ||= DEFAULTS.dup
|
32
32
|
end
|
33
33
|
|
34
|
-
def register_worker(queue, clazz)
|
35
|
-
if worker_class = @@workers[queue]
|
36
|
-
if worker_class.get_shoryuken_options['batch'] == true || clazz.get_shoryuken_options['batch'] == true
|
37
|
-
raise ArgumentError, "Could not register #{clazz} for '#{queue}', "\
|
38
|
-
"because #{worker_class} is already registered for this queue, "\
|
39
|
-
"and Shoryuken doesn't support a batchable worker for a queue with multiple workers"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
@@workers[queue] = clazz
|
44
|
-
end
|
45
|
-
|
46
|
-
def workers
|
47
|
-
@@workers
|
48
|
-
end
|
49
|
-
|
50
34
|
def queues
|
51
35
|
@@queues
|
52
36
|
end
|
@@ -55,12 +39,16 @@ module Shoryuken
|
|
55
39
|
Shoryuken::Logging.logger
|
56
40
|
end
|
57
41
|
|
58
|
-
def
|
59
|
-
|
42
|
+
def register_worker(*args)
|
43
|
+
worker_registry.register_worker(*args)
|
60
44
|
end
|
61
45
|
|
62
|
-
def
|
63
|
-
@@
|
46
|
+
def worker_registry=(worker_registry)
|
47
|
+
@@worker_registry = worker_registry
|
48
|
+
end
|
49
|
+
|
50
|
+
def worker_registry
|
51
|
+
@@worker_registry
|
64
52
|
end
|
65
53
|
|
66
54
|
# Shoryuken.configure_server do |config|
|
@@ -78,6 +66,18 @@ module Shoryuken
|
|
78
66
|
@server_chain
|
79
67
|
end
|
80
68
|
|
69
|
+
def default_worker_options
|
70
|
+
@@default_worker_options ||= {
|
71
|
+
'queue' => 'default',
|
72
|
+
'delete' => false,
|
73
|
+
'auto_delete' => false,
|
74
|
+
'auto_visibility_timeout' => false,
|
75
|
+
'batch' => false }
|
76
|
+
end
|
77
|
+
|
78
|
+
def default_worker_options=(options)
|
79
|
+
@@default_worker_options = options
|
80
|
+
end
|
81
81
|
|
82
82
|
private
|
83
83
|
|
@@ -89,8 +89,9 @@ module Shoryuken
|
|
89
89
|
require 'shoryuken/middleware/server/active_record'
|
90
90
|
m.add Middleware::Server::ActiveRecord
|
91
91
|
end
|
92
|
-
# TODO m.add Middleware::Server::RetryJobs
|
93
92
|
end
|
94
93
|
end
|
95
94
|
end
|
96
95
|
end
|
96
|
+
|
97
|
+
require 'shoryuken/extensions/active_job_adapter' if defined?(::ActiveJob)
|
data/lib/shoryuken/cli.rb
CHANGED
@@ -7,6 +7,9 @@ require 'erb'
|
|
7
7
|
require 'shoryuken'
|
8
8
|
|
9
9
|
module Shoryuken
|
10
|
+
# See: https://github.com/mperham/sidekiq/blob/33f5d6b2b6c0dfaab11e5d39688cab7ebadc83ae/lib/sidekiq/cli.rb#L20
|
11
|
+
class Shutdown < Interrupt; end
|
12
|
+
|
10
13
|
class CLI
|
11
14
|
include Util
|
12
15
|
include Singleton
|
@@ -24,9 +27,9 @@ module Shoryuken
|
|
24
27
|
|
25
28
|
setup_options(args) do |cli_options|
|
26
29
|
# this needs to happen before configuration is parsed, since it may depend on Rails env
|
30
|
+
initialize_logger(cli_options)
|
27
31
|
load_rails if cli_options[:rails]
|
28
32
|
end
|
29
|
-
initialize_logger
|
30
33
|
require_workers
|
31
34
|
validate!
|
32
35
|
patch_deprecated_workers!
|
@@ -77,6 +80,7 @@ module Shoryuken
|
|
77
80
|
::Rails::Application.initializer "shoryuken.eager_load" do
|
78
81
|
::Rails.application.config.eager_load = true
|
79
82
|
end
|
83
|
+
require 'shoryuken/extensions/active_job_adapter' if defined?(::ActiveJob)
|
80
84
|
require File.expand_path("config/environment.rb")
|
81
85
|
end
|
82
86
|
|
@@ -233,22 +237,21 @@ module Shoryuken
|
|
233
237
|
end
|
234
238
|
end
|
235
239
|
|
236
|
-
def initialize_logger
|
237
|
-
Shoryuken::Logging.initialize_logger(
|
240
|
+
def initialize_logger(options = Shoryuken.options)
|
241
|
+
Shoryuken::Logging.initialize_logger(options[:logfile]) if options[:logfile]
|
238
242
|
|
239
|
-
Shoryuken.logger.level = Logger::DEBUG if
|
243
|
+
Shoryuken.logger.level = Logger::DEBUG if options[:verbose]
|
240
244
|
end
|
241
245
|
|
242
246
|
def validate!
|
243
247
|
raise ArgumentError, 'No queues supplied' if Shoryuken.queues.empty?
|
244
248
|
|
245
|
-
Shoryuken.queues
|
246
|
-
|
247
|
-
end
|
249
|
+
all_queues = Shoryuken.queues
|
250
|
+
queues_with_workers = Shoryuken.worker_registry.queues
|
248
251
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
+
unless defined?(::ActiveJob)
|
253
|
+
(all_queues - queues_with_workers).each do |queue|
|
254
|
+
logger.warn "No worker supplied for '#{queue}'"
|
252
255
|
end
|
253
256
|
end
|
254
257
|
|
@@ -285,15 +288,17 @@ module Shoryuken
|
|
285
288
|
end
|
286
289
|
|
287
290
|
def patch_deprecated_workers!
|
288
|
-
Shoryuken.
|
289
|
-
|
290
|
-
|
291
|
+
Shoryuken.worker_registry.queues.each do |queue|
|
292
|
+
Shoryuken.worker_registry.workers(queue).each do |worker_class|
|
293
|
+
if worker_class.instance_method(:perform).arity == 1
|
294
|
+
logger.warn "[DEPRECATION] #{worker_class.name}#perform(sqs_msg) is deprecated. Please use #{worker_class.name}#perform(sqs_msg, body)"
|
291
295
|
|
292
|
-
|
293
|
-
|
296
|
+
worker_class.class_eval do
|
297
|
+
alias_method :deprecated_perform, :perform
|
294
298
|
|
295
|
-
|
296
|
-
|
299
|
+
def perform(sqs_msg, body = nil)
|
300
|
+
deprecated_perform(sqs_msg)
|
301
|
+
end
|
297
302
|
end
|
298
303
|
end
|
299
304
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Shoryuken
|
2
|
+
class DefaultWorkerRegistry < WorkerRegistry
|
3
|
+
def initialize
|
4
|
+
@workers = {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def batch_receive_messages?(queue)
|
8
|
+
!!(@workers[queue] && @workers[queue].get_shoryuken_options['batch'])
|
9
|
+
end
|
10
|
+
|
11
|
+
def clear
|
12
|
+
@workers.clear
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch_worker(queue, message)
|
16
|
+
worker_class = !message.is_a?(Array) &&
|
17
|
+
message.message_attributes &&
|
18
|
+
message.message_attributes['shoryuken_class'] &&
|
19
|
+
message.message_attributes['shoryuken_class'][:string_value]
|
20
|
+
|
21
|
+
worker_class = (worker_class.constantize rescue nil) || @workers[queue]
|
22
|
+
|
23
|
+
worker_class.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def queues
|
27
|
+
@workers.keys
|
28
|
+
end
|
29
|
+
|
30
|
+
def register_worker(queue, clazz)
|
31
|
+
if worker_class = @workers[queue]
|
32
|
+
if worker_class.get_shoryuken_options['batch'] == true || clazz.get_shoryuken_options['batch'] == true
|
33
|
+
raise ArgumentError, "Could not register #{clazz} for '#{queue}', "\
|
34
|
+
"because #{worker_class} is already registered for this queue, "\
|
35
|
+
"and Shoryuken doesn't support a batchable worker for a queue with multiple workers."
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
@workers[queue] = clazz
|
40
|
+
end
|
41
|
+
|
42
|
+
def workers(queue)
|
43
|
+
[@workers.fetch(queue, [])].flatten
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# ActiveJob docs: http://edgeguides.rubyonrails.org/active_job_basics.html
|
2
|
+
# Example adapters ref: https://github.com/rails/rails/tree/master/activejob/lib/active_job/queue_adapters
|
3
|
+
|
4
|
+
require 'shoryuken'
|
5
|
+
|
6
|
+
module ActiveJob
|
7
|
+
module QueueAdapters
|
8
|
+
# == Shoryuken adapter for Active Job
|
9
|
+
#
|
10
|
+
# Shoryuken ("sho-ryu-ken") is a super-efficient AWS SQS thread based message processor.
|
11
|
+
#
|
12
|
+
# Read more about Shoryuken {here}[https://github.com/phstc/shoryuken].
|
13
|
+
#
|
14
|
+
# To use Shoryuken set the queue_adapter config to +:shoryuken+.
|
15
|
+
#
|
16
|
+
# Rails.application.config.active_job.queue_adapter = :shoryuken
|
17
|
+
class ShoryukenAdapter
|
18
|
+
class << self
|
19
|
+
def enqueue(job) #:nodoc:
|
20
|
+
register_worker!(job)
|
21
|
+
|
22
|
+
Shoryuken::Client.send_message(job.queue_name, job.serialize, message_attributes: message_attributes)
|
23
|
+
end
|
24
|
+
|
25
|
+
def enqueue_at(job, timestamp) #:nodoc:
|
26
|
+
register_worker!(job)
|
27
|
+
|
28
|
+
delay = (timestamp - Time.current.to_f).round
|
29
|
+
raise 'The maximum allowed delay is 15 minutes' if delay > 15.minutes
|
30
|
+
|
31
|
+
Shoryuken::Client.send_message(job.queue_name, job.serialize, delay_seconds: delay,
|
32
|
+
message_attributes: message_attributes)
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def register_worker!(job)
|
39
|
+
Shoryuken.register_worker(job.queue_name, JobWrapper)
|
40
|
+
end
|
41
|
+
|
42
|
+
def message_attributes
|
43
|
+
@message_attributes ||= {
|
44
|
+
'shoryuken_class' => {
|
45
|
+
string_value: JobWrapper.to_s,
|
46
|
+
data_type: 'String'
|
47
|
+
}
|
48
|
+
}
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
class JobWrapper #:nodoc:
|
53
|
+
include Shoryuken::Worker
|
54
|
+
|
55
|
+
shoryuken_options body_parser: :json, auto_delete: true
|
56
|
+
|
57
|
+
def perform(sqs_msg, hash)
|
58
|
+
Base.execute hash
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/shoryuken/fetcher.rb
CHANGED
@@ -13,7 +13,7 @@ module Shoryuken
|
|
13
13
|
# AWS limits the batch size by 10
|
14
14
|
limit = limit > FETCH_LIMIT ? FETCH_LIMIT : limit
|
15
15
|
|
16
|
-
options = Shoryuken.options[:aws][:receive_message].to_h
|
16
|
+
options = Shoryuken.options[:aws][:receive_message].to_h.dup
|
17
17
|
options[:limit] = limit
|
18
18
|
options[:message_attribute_names] ||= []
|
19
19
|
options[:message_attribute_names] << 'shoryuken_class'
|
@@ -28,8 +28,7 @@ module Shoryuken
|
|
28
28
|
logger.debug "Looking for new messages in '#{queue}'"
|
29
29
|
|
30
30
|
begin
|
31
|
-
batch =
|
32
|
-
|
31
|
+
batch = Shoryuken.worker_registry.batch_receive_messages?(queue)
|
33
32
|
limit = batch ? FETCH_LIMIT : available_processors
|
34
33
|
|
35
34
|
if (sqs_msgs = Array(receive_message(queue, limit))).any?
|
data/lib/shoryuken/launcher.rb
CHANGED
@@ -8,7 +8,8 @@ module Shoryuken
|
|
8
8
|
attr_accessor :manager
|
9
9
|
|
10
10
|
def initialize
|
11
|
-
@
|
11
|
+
@condvar = Celluloid::Condition.new
|
12
|
+
@manager = Shoryuken::Manager.new_link(@condvar)
|
12
13
|
@fetcher = Shoryuken::Fetcher.new_link(manager)
|
13
14
|
|
14
15
|
@done = false
|
@@ -22,7 +23,8 @@ module Shoryuken
|
|
22
23
|
@fetcher.terminate if @fetcher.alive?
|
23
24
|
|
24
25
|
manager.async.stop(shutdown: !!options[:shutdown], timeout: Shoryuken.options[:timeout])
|
25
|
-
|
26
|
+
@condvar.wait
|
27
|
+
manager.terminate
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
data/lib/shoryuken/manager.rb
CHANGED
@@ -10,14 +10,16 @@ module Shoryuken
|
|
10
10
|
|
11
11
|
trap_exit :processor_died
|
12
12
|
|
13
|
-
def initialize
|
13
|
+
def initialize(condvar)
|
14
14
|
@count = Shoryuken.options[:concurrency] || 25
|
15
15
|
@queues = Shoryuken.queues.dup.uniq
|
16
|
+
@finished = condvar
|
16
17
|
|
17
18
|
@done = false
|
18
19
|
|
19
20
|
@busy = []
|
20
|
-
@ready = @count.times.map {
|
21
|
+
@ready = @count.times.map { build_processor }
|
22
|
+
@threads = {}
|
21
23
|
end
|
22
24
|
|
23
25
|
def start
|
@@ -39,7 +41,7 @@ module Shoryuken
|
|
39
41
|
end
|
40
42
|
@ready.clear
|
41
43
|
|
42
|
-
return after(0) { signal
|
44
|
+
return after(0) { @finished.signal } if @busy.empty?
|
43
45
|
|
44
46
|
if options[:shutdown]
|
45
47
|
hard_shutdown_in(options[:timeout])
|
@@ -53,6 +55,7 @@ module Shoryuken
|
|
53
55
|
watchdog('Manager#processor_done died') do
|
54
56
|
logger.info "Process done for '#{queue}'"
|
55
57
|
|
58
|
+
@threads.delete(processor.object_id)
|
56
59
|
@busy.delete processor
|
57
60
|
|
58
61
|
if stopped?
|
@@ -65,12 +68,13 @@ module Shoryuken
|
|
65
68
|
|
66
69
|
def processor_died(processor, reason)
|
67
70
|
watchdog("Manager#processor_died died") do
|
68
|
-
logger.
|
71
|
+
logger.error "Process died, reason: #{reason}" unless reason.to_s.empty?
|
69
72
|
|
73
|
+
@threads.delete(processor.object_id)
|
70
74
|
@busy.delete processor
|
71
75
|
|
72
76
|
unless stopped?
|
73
|
-
@ready <<
|
77
|
+
@ready << build_processor
|
74
78
|
end
|
75
79
|
end
|
76
80
|
end
|
@@ -133,8 +137,18 @@ module Shoryuken
|
|
133
137
|
end
|
134
138
|
end
|
135
139
|
|
140
|
+
def real_thread(proxy_id, thr)
|
141
|
+
@threads[proxy_id] = thr
|
142
|
+
end
|
143
|
+
|
136
144
|
private
|
137
145
|
|
146
|
+
def build_processor
|
147
|
+
processor = Processor.new_link(current_actor)
|
148
|
+
processor.proxy_id = processor.object_id
|
149
|
+
processor
|
150
|
+
end
|
151
|
+
|
138
152
|
def restart_queue!(queue)
|
139
153
|
return if stopped?
|
140
154
|
|
@@ -148,7 +162,6 @@ module Shoryuken
|
|
148
162
|
|
149
163
|
@fetcher_paused = false
|
150
164
|
|
151
|
-
|
152
165
|
dispatch
|
153
166
|
end
|
154
167
|
end
|
@@ -172,11 +185,10 @@ module Shoryuken
|
|
172
185
|
# get/remove the first queue in the list
|
173
186
|
queue = @queues.shift
|
174
187
|
|
175
|
-
|
176
|
-
unless Shoryuken.workers.include? queue
|
188
|
+
unless defined?(::ActiveJob) || !Shoryuken.worker_registry.workers(queue).empty?
|
177
189
|
# when no worker registered pause the queue to avoid endless recursion
|
178
190
|
|
179
|
-
logger.debug "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because
|
191
|
+
logger.debug "Pausing '#{queue}' for #{Shoryuken.options[:delay].to_f} seconds, because no workers registered"
|
180
192
|
|
181
193
|
after(Shoryuken.options[:delay].to_f) { async.restart_queue!(queue) }
|
182
194
|
|
@@ -195,7 +207,7 @@ module Shoryuken
|
|
195
207
|
if @busy.size > 0
|
196
208
|
after(delay) { soft_shutdown(delay) }
|
197
209
|
else
|
198
|
-
|
210
|
+
@finished.signal
|
199
211
|
end
|
200
212
|
end
|
201
213
|
|
@@ -209,12 +221,13 @@ module Shoryuken
|
|
209
221
|
logger.info { "Hard shutting down #{@busy.size} busy workers" }
|
210
222
|
|
211
223
|
@busy.each do |processor|
|
212
|
-
t = processor.
|
213
|
-
|
224
|
+
if processor.alive? && t = @threads.delete(processor.object_id)
|
225
|
+
t.raise Shutdown
|
226
|
+
end
|
214
227
|
end
|
215
228
|
end
|
216
229
|
|
217
|
-
|
230
|
+
@finished.signal
|
218
231
|
end
|
219
232
|
end
|
220
233
|
end
|