shoryuken 2.1.0 → 3.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 +4 -4
- data/.codeclimate.yml +5 -8
- data/.rubocop.yml +8 -2
- data/.travis.yml +5 -0
- data/CHANGELOG.md +88 -11
- data/README.md +20 -57
- data/Rakefile +0 -1
- data/bin/cli/base.rb +42 -0
- data/bin/cli/sqs.rb +188 -0
- data/bin/shoryuken +47 -9
- data/examples/default_worker.rb +1 -1
- data/lib/shoryuken/client.rb +3 -15
- data/lib/shoryuken/default_worker_registry.rb +9 -5
- data/lib/shoryuken/environment_loader.rb +11 -40
- data/lib/shoryuken/fetcher.rb +22 -53
- data/lib/shoryuken/launcher.rb +5 -29
- data/lib/shoryuken/manager.rb +72 -190
- data/lib/shoryuken/message.rb +4 -13
- data/lib/shoryuken/middleware/chain.rb +1 -18
- data/lib/shoryuken/middleware/server/auto_extend_visibility.rb +13 -14
- data/lib/shoryuken/middleware/server/exponential_backoff_retry.rb +29 -20
- data/lib/shoryuken/polling.rb +204 -0
- data/lib/shoryuken/processor.rb +6 -14
- data/lib/shoryuken/queue.rb +1 -3
- data/lib/shoryuken/runner.rb +143 -0
- data/lib/shoryuken/util.rb +0 -8
- data/lib/shoryuken/version.rb +1 -1
- data/lib/shoryuken/worker.rb +1 -1
- data/lib/shoryuken.rb +77 -55
- data/shoryuken.gemspec +6 -6
- data/spec/integration/launcher_spec.rb +4 -3
- data/spec/shoryuken/client_spec.rb +2 -45
- data/spec/shoryuken/default_worker_registry_spec.rb +12 -10
- data/spec/shoryuken/environment_loader_spec.rb +34 -0
- data/spec/shoryuken/fetcher_spec.rb +18 -52
- data/spec/shoryuken/manager_spec.rb +56 -97
- data/spec/shoryuken/middleware/chain_spec.rb +0 -24
- data/spec/shoryuken/middleware/server/auto_delete_spec.rb +2 -2
- data/spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb +7 -3
- data/spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb +56 -33
- data/spec/shoryuken/polling_spec.rb +239 -0
- data/spec/shoryuken/processor_spec.rb +5 -5
- data/spec/shoryuken/{cli_spec.rb → runner_spec.rb} +8 -22
- data/spec/shoryuken_spec.rb +13 -1
- data/spec/spec_helper.rb +3 -18
- data/test_workers/endless_interruptive_worker.rb +41 -0
- data/test_workers/endless_uninterruptive_worker.rb +44 -0
- metadata +32 -34
- data/lib/shoryuken/aws_config.rb +0 -64
- data/lib/shoryuken/cli.rb +0 -215
- data/lib/shoryuken/sns_arn.rb +0 -27
- data/lib/shoryuken/topic.rb +0 -17
- data/spec/shoryuken/sns_arn_spec.rb +0 -42
- data/spec/shoryuken/topic_spec.rb +0 -32
- data/spec/shoryuken_endpoint.yml +0 -6
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
class EndlessUninterruptiveWorker
|
|
2
|
+
include Shoryuken::Worker
|
|
3
|
+
|
|
4
|
+
# Usage:
|
|
5
|
+
# QUEUE="super-q"
|
|
6
|
+
# MAX_EXECUTION_TIME=2000 QUEUE=$QUEUE \
|
|
7
|
+
# bundle exec ./bin/shoryuken -r ./examples/endless_interruptive_worker.rb -q $QUEUE -c 8
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
def queue
|
|
11
|
+
ENV['QUEUE'] || 'default'
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def max_execution_time
|
|
15
|
+
ENV["MAX_EXECUTION_TIME"] ? ENV["MAX_EXECUTION_TIME"].to_i : 100
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def rng
|
|
19
|
+
@rng ||= Random.new
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# returns a random number between 0 and 100
|
|
23
|
+
def random_number(hi = 1000)
|
|
24
|
+
(rng.rand * hi).to_i
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def perform(sqs_msg, body)
|
|
29
|
+
Shoryuken.logger.info("Received message: '#{body}'")
|
|
30
|
+
|
|
31
|
+
execution_ms = self.class.random_number(self.class.max_execution_time)
|
|
32
|
+
Shoryuken.logger.info("Going to burn metal for #{execution_ms}ms")
|
|
33
|
+
end_time = Time.now + execution_ms.to_f / 1000
|
|
34
|
+
while Time.now < end_time do
|
|
35
|
+
# burn metal
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
new_body = "#{execution_ms}-" + body.to_s
|
|
39
|
+
|
|
40
|
+
self.class.perform_async(new_body.slice(0, 512))
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
shoryuken_options queue: queue, auto_delete: true
|
|
44
|
+
end
|
metadata
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: shoryuken
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 3.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pablo Cantero
|
|
8
|
-
- Mario Kostelac
|
|
9
8
|
autorequire:
|
|
10
9
|
bindir: bin
|
|
11
10
|
cert_chain: []
|
|
12
|
-
date:
|
|
11
|
+
date: 2017-03-12 00:00:00.000000000 Z
|
|
13
12
|
dependencies:
|
|
14
13
|
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: bundler
|
|
@@ -68,7 +67,7 @@ dependencies:
|
|
|
68
67
|
- !ruby/object:Gem::Version
|
|
69
68
|
version: '0'
|
|
70
69
|
- !ruby/object:Gem::Dependency
|
|
71
|
-
name:
|
|
70
|
+
name: dotenv
|
|
72
71
|
requirement: !ruby/object:Gem::Requirement
|
|
73
72
|
requirements:
|
|
74
73
|
- - ">="
|
|
@@ -82,51 +81,50 @@ dependencies:
|
|
|
82
81
|
- !ruby/object:Gem::Version
|
|
83
82
|
version: '0'
|
|
84
83
|
- !ruby/object:Gem::Dependency
|
|
85
|
-
name:
|
|
84
|
+
name: aws-sdk-core
|
|
86
85
|
requirement: !ruby/object:Gem::Requirement
|
|
87
86
|
requirements:
|
|
88
|
-
- - "
|
|
87
|
+
- - "~>"
|
|
89
88
|
- !ruby/object:Gem::Version
|
|
90
|
-
version: '
|
|
91
|
-
type: :
|
|
89
|
+
version: '2'
|
|
90
|
+
type: :runtime
|
|
92
91
|
prerelease: false
|
|
93
92
|
version_requirements: !ruby/object:Gem::Requirement
|
|
94
93
|
requirements:
|
|
95
|
-
- - "
|
|
94
|
+
- - "~>"
|
|
96
95
|
- !ruby/object:Gem::Version
|
|
97
|
-
version: '
|
|
96
|
+
version: '2'
|
|
98
97
|
- !ruby/object:Gem::Dependency
|
|
99
|
-
name:
|
|
98
|
+
name: concurrent-ruby
|
|
100
99
|
requirement: !ruby/object:Gem::Requirement
|
|
101
100
|
requirements:
|
|
102
|
-
- - "
|
|
101
|
+
- - ">="
|
|
103
102
|
- !ruby/object:Gem::Version
|
|
104
|
-
version: '
|
|
103
|
+
version: '0'
|
|
105
104
|
type: :runtime
|
|
106
105
|
prerelease: false
|
|
107
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
108
107
|
requirements:
|
|
109
|
-
- - "
|
|
108
|
+
- - ">="
|
|
110
109
|
- !ruby/object:Gem::Version
|
|
111
|
-
version: '
|
|
110
|
+
version: '0'
|
|
112
111
|
- !ruby/object:Gem::Dependency
|
|
113
|
-
name:
|
|
112
|
+
name: thor
|
|
114
113
|
requirement: !ruby/object:Gem::Requirement
|
|
115
114
|
requirements:
|
|
116
|
-
- - "
|
|
115
|
+
- - ">="
|
|
117
116
|
- !ruby/object:Gem::Version
|
|
118
|
-
version: '0
|
|
117
|
+
version: '0'
|
|
119
118
|
type: :runtime
|
|
120
119
|
prerelease: false
|
|
121
120
|
version_requirements: !ruby/object:Gem::Requirement
|
|
122
121
|
requirements:
|
|
123
|
-
- - "
|
|
122
|
+
- - ">="
|
|
124
123
|
- !ruby/object:Gem::Version
|
|
125
|
-
version: '0
|
|
124
|
+
version: '0'
|
|
126
125
|
description: Shoryuken is a super efficient AWS SQS thread based message processor
|
|
127
126
|
email:
|
|
128
127
|
- pablo@pablocantero.com
|
|
129
|
-
- mariokostelac@gmail.com
|
|
130
128
|
executables:
|
|
131
129
|
- shoryuken
|
|
132
130
|
extensions: []
|
|
@@ -142,12 +140,12 @@ files:
|
|
|
142
140
|
- LICENSE
|
|
143
141
|
- README.md
|
|
144
142
|
- Rakefile
|
|
143
|
+
- bin/cli/base.rb
|
|
144
|
+
- bin/cli/sqs.rb
|
|
145
145
|
- bin/shoryuken
|
|
146
146
|
- examples/bootstrap_queues.rb
|
|
147
147
|
- examples/default_worker.rb
|
|
148
148
|
- lib/shoryuken.rb
|
|
149
|
-
- lib/shoryuken/aws_config.rb
|
|
150
|
-
- lib/shoryuken/cli.rb
|
|
151
149
|
- lib/shoryuken/client.rb
|
|
152
150
|
- lib/shoryuken/core_ext.rb
|
|
153
151
|
- lib/shoryuken/default_worker_registry.rb
|
|
@@ -164,10 +162,10 @@ files:
|
|
|
164
162
|
- lib/shoryuken/middleware/server/auto_extend_visibility.rb
|
|
165
163
|
- lib/shoryuken/middleware/server/exponential_backoff_retry.rb
|
|
166
164
|
- lib/shoryuken/middleware/server/timing.rb
|
|
165
|
+
- lib/shoryuken/polling.rb
|
|
167
166
|
- lib/shoryuken/processor.rb
|
|
168
167
|
- lib/shoryuken/queue.rb
|
|
169
|
-
- lib/shoryuken/
|
|
170
|
-
- lib/shoryuken/topic.rb
|
|
168
|
+
- lib/shoryuken/runner.rb
|
|
171
169
|
- lib/shoryuken/util.rb
|
|
172
170
|
- lib/shoryuken/version.rb
|
|
173
171
|
- lib/shoryuken/worker.rb
|
|
@@ -176,10 +174,10 @@ files:
|
|
|
176
174
|
- shoryuken.jpg
|
|
177
175
|
- spec/integration/launcher_spec.rb
|
|
178
176
|
- spec/shoryuken.yml
|
|
179
|
-
- spec/shoryuken/cli_spec.rb
|
|
180
177
|
- spec/shoryuken/client_spec.rb
|
|
181
178
|
- spec/shoryuken/core_ext_spec.rb
|
|
182
179
|
- spec/shoryuken/default_worker_registry_spec.rb
|
|
180
|
+
- spec/shoryuken/environment_loader_spec.rb
|
|
183
181
|
- spec/shoryuken/fetcher_spec.rb
|
|
184
182
|
- spec/shoryuken/manager_spec.rb
|
|
185
183
|
- spec/shoryuken/middleware/chain_spec.rb
|
|
@@ -187,15 +185,16 @@ files:
|
|
|
187
185
|
- spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb
|
|
188
186
|
- spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb
|
|
189
187
|
- spec/shoryuken/middleware/server/timing_spec.rb
|
|
188
|
+
- spec/shoryuken/polling_spec.rb
|
|
190
189
|
- spec/shoryuken/processor_spec.rb
|
|
191
190
|
- spec/shoryuken/queue_spec.rb
|
|
192
|
-
- spec/shoryuken/
|
|
193
|
-
- spec/shoryuken/topic_spec.rb
|
|
191
|
+
- spec/shoryuken/runner_spec.rb
|
|
194
192
|
- spec/shoryuken/util_spec.rb
|
|
195
193
|
- spec/shoryuken/worker_spec.rb
|
|
196
|
-
- spec/shoryuken_endpoint.yml
|
|
197
194
|
- spec/shoryuken_spec.rb
|
|
198
195
|
- spec/spec_helper.rb
|
|
196
|
+
- test_workers/endless_interruptive_worker.rb
|
|
197
|
+
- test_workers/endless_uninterruptive_worker.rb
|
|
199
198
|
homepage: https://github.com/phstc/shoryuken
|
|
200
199
|
licenses:
|
|
201
200
|
- LGPL-3.0
|
|
@@ -216,17 +215,17 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
216
215
|
version: '0'
|
|
217
216
|
requirements: []
|
|
218
217
|
rubyforge_project:
|
|
219
|
-
rubygems_version: 2.5.
|
|
218
|
+
rubygems_version: 2.5.2
|
|
220
219
|
signing_key:
|
|
221
220
|
specification_version: 4
|
|
222
221
|
summary: Shoryuken is a super efficient AWS SQS thread based message processor
|
|
223
222
|
test_files:
|
|
224
223
|
- spec/integration/launcher_spec.rb
|
|
225
224
|
- spec/shoryuken.yml
|
|
226
|
-
- spec/shoryuken/cli_spec.rb
|
|
227
225
|
- spec/shoryuken/client_spec.rb
|
|
228
226
|
- spec/shoryuken/core_ext_spec.rb
|
|
229
227
|
- spec/shoryuken/default_worker_registry_spec.rb
|
|
228
|
+
- spec/shoryuken/environment_loader_spec.rb
|
|
230
229
|
- spec/shoryuken/fetcher_spec.rb
|
|
231
230
|
- spec/shoryuken/manager_spec.rb
|
|
232
231
|
- spec/shoryuken/middleware/chain_spec.rb
|
|
@@ -234,12 +233,11 @@ test_files:
|
|
|
234
233
|
- spec/shoryuken/middleware/server/auto_extend_visibility_spec.rb
|
|
235
234
|
- spec/shoryuken/middleware/server/exponential_backoff_retry_spec.rb
|
|
236
235
|
- spec/shoryuken/middleware/server/timing_spec.rb
|
|
236
|
+
- spec/shoryuken/polling_spec.rb
|
|
237
237
|
- spec/shoryuken/processor_spec.rb
|
|
238
238
|
- spec/shoryuken/queue_spec.rb
|
|
239
|
-
- spec/shoryuken/
|
|
240
|
-
- spec/shoryuken/topic_spec.rb
|
|
239
|
+
- spec/shoryuken/runner_spec.rb
|
|
241
240
|
- spec/shoryuken/util_spec.rb
|
|
242
241
|
- spec/shoryuken/worker_spec.rb
|
|
243
|
-
- spec/shoryuken_endpoint.yml
|
|
244
242
|
- spec/shoryuken_spec.rb
|
|
245
243
|
- spec/spec_helper.rb
|
data/lib/shoryuken/aws_config.rb
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
module Shoryuken
|
|
3
|
-
class AwsConfig
|
|
4
|
-
class << self
|
|
5
|
-
attr_writer :options
|
|
6
|
-
|
|
7
|
-
def options
|
|
8
|
-
@options ||= {}
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def setup(hash)
|
|
12
|
-
# aws-sdk tries to load the credentials from the ENV variables: AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
|
|
13
|
-
# when not explicit supplied
|
|
14
|
-
return if hash.empty?
|
|
15
|
-
|
|
16
|
-
self.options = hash
|
|
17
|
-
|
|
18
|
-
shoryuken_keys = %w(
|
|
19
|
-
account_id
|
|
20
|
-
sns_endpoint
|
|
21
|
-
sqs_endpoint
|
|
22
|
-
receive_message
|
|
23
|
-
).map(&:to_sym)
|
|
24
|
-
|
|
25
|
-
@aws_options = hash.reject do |k, _|
|
|
26
|
-
shoryuken_keys.include?(k)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# assume credentials based authentication
|
|
30
|
-
credentials = Aws::Credentials.new(
|
|
31
|
-
@aws_options.delete(:access_key_id),
|
|
32
|
-
@aws_options.delete(:secret_access_key)
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
# but only if the configuration options have valid values
|
|
36
|
-
@aws_options.merge!(credentials: credentials) if credentials.set?
|
|
37
|
-
|
|
38
|
-
if (callback = Shoryuken.aws_initialization_callback)
|
|
39
|
-
Shoryuken.logger.info { 'Calling Shoryuken.on_aws_initialization block' }
|
|
40
|
-
callback.call(@aws_options)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def sns
|
|
45
|
-
Aws::SNS::Client.new(aws_client_options(:sns_endpoint))
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def sqs
|
|
49
|
-
Aws::SQS::Client.new(aws_client_options(:sqs_endpoint))
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
def aws_client_options(service_endpoint_key)
|
|
55
|
-
environment_endpoint = ENV["AWS_#{service_endpoint_key.to_s.upcase}"]
|
|
56
|
-
explicit_endpoint = options[service_endpoint_key] || environment_endpoint
|
|
57
|
-
endpoint = {}.tap do |hash|
|
|
58
|
-
hash[:endpoint] = explicit_endpoint unless explicit_endpoint.to_s.empty?
|
|
59
|
-
end
|
|
60
|
-
@aws_options.to_h.merge(endpoint)
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|
data/lib/shoryuken/cli.rb
DELETED
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
$stdout.sync = true
|
|
2
|
-
|
|
3
|
-
require 'singleton'
|
|
4
|
-
require 'optparse'
|
|
5
|
-
require 'erb'
|
|
6
|
-
|
|
7
|
-
require 'shoryuken'
|
|
8
|
-
|
|
9
|
-
module Shoryuken
|
|
10
|
-
# See: https://github.com/mperham/sidekiq/blob/33f5d6b2b6c0dfaab11e5d39688cab7ebadc83ae/lib/sidekiq/cli.rb#L20
|
|
11
|
-
class Shutdown < Interrupt; end
|
|
12
|
-
|
|
13
|
-
class CLI
|
|
14
|
-
include Util
|
|
15
|
-
include Singleton
|
|
16
|
-
|
|
17
|
-
attr_accessor :launcher
|
|
18
|
-
|
|
19
|
-
def run(args)
|
|
20
|
-
self_read, self_write = IO.pipe
|
|
21
|
-
|
|
22
|
-
%w(INT TERM USR1 USR2 TTIN).each do |sig|
|
|
23
|
-
begin
|
|
24
|
-
trap sig do
|
|
25
|
-
self_write.puts(sig)
|
|
26
|
-
end
|
|
27
|
-
rescue ArgumentError
|
|
28
|
-
puts "Signal #{sig} not supported"
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
options = parse_cli_args(args)
|
|
33
|
-
|
|
34
|
-
loader = EnvironmentLoader.setup_options(options)
|
|
35
|
-
|
|
36
|
-
# When cli args exist, override options in config file
|
|
37
|
-
Shoryuken.options.merge!(options)
|
|
38
|
-
|
|
39
|
-
daemonize(Shoryuken.options)
|
|
40
|
-
write_pid(Shoryuken.options)
|
|
41
|
-
|
|
42
|
-
loader.load
|
|
43
|
-
|
|
44
|
-
load_celluloid
|
|
45
|
-
|
|
46
|
-
require 'shoryuken/launcher'
|
|
47
|
-
@launcher = Shoryuken::Launcher.new
|
|
48
|
-
|
|
49
|
-
if callback = Shoryuken.start_callback
|
|
50
|
-
logger.info { 'Calling Shoryuken.on_start block' }
|
|
51
|
-
callback.call
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
fire_event(:startup)
|
|
55
|
-
|
|
56
|
-
begin
|
|
57
|
-
launcher.run
|
|
58
|
-
|
|
59
|
-
while (readable_io = IO.select([self_read]))
|
|
60
|
-
signal = readable_io.first[0].gets.strip
|
|
61
|
-
handle_signal(signal)
|
|
62
|
-
end
|
|
63
|
-
rescue Interrupt
|
|
64
|
-
launcher.stop(shutdown: true)
|
|
65
|
-
exit 0
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
private
|
|
70
|
-
|
|
71
|
-
def load_celluloid
|
|
72
|
-
require 'celluloid/current'
|
|
73
|
-
Celluloid.logger = (Shoryuken.options[:verbose] ? Shoryuken.logger : nil)
|
|
74
|
-
|
|
75
|
-
require 'shoryuken/manager'
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
def celluloid_loaded?
|
|
79
|
-
defined?(::Celluloid)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def daemonize(options)
|
|
83
|
-
return unless options[:daemon]
|
|
84
|
-
|
|
85
|
-
fail ArgumentError, "You really should set a logfile if you're going to daemonize" unless options[:logfile]
|
|
86
|
-
|
|
87
|
-
if celluloid_loaded?
|
|
88
|
-
# Celluloid can't be loaded until after we've daemonized
|
|
89
|
-
# because it spins up threads and creates locks which get
|
|
90
|
-
# into a very bad state if forked.
|
|
91
|
-
raise "Celluloid cannot be required until here, or it will break Shoryuken's daemonization"
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
files_to_reopen = []
|
|
95
|
-
ObjectSpace.each_object(File) do |file|
|
|
96
|
-
files_to_reopen << file unless file.closed?
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
Process.daemon(true, true)
|
|
100
|
-
|
|
101
|
-
files_to_reopen.each do |file|
|
|
102
|
-
begin
|
|
103
|
-
file.reopen file.path, 'a+'
|
|
104
|
-
file.sync = true
|
|
105
|
-
rescue ::Exception
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
[$stdout, $stderr].each do |io|
|
|
110
|
-
File.open(options[:logfile], 'ab') do |f|
|
|
111
|
-
io.reopen(f)
|
|
112
|
-
end
|
|
113
|
-
io.sync = true
|
|
114
|
-
end
|
|
115
|
-
$stdin.reopen('/dev/null')
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def write_pid(options)
|
|
119
|
-
if (path = options[:pidfile])
|
|
120
|
-
File.open(path, 'w') do |f|
|
|
121
|
-
f.puts Process.pid
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def parse_cli_args(argv)
|
|
127
|
-
opts = {}
|
|
128
|
-
|
|
129
|
-
@parser = OptionParser.new do |o|
|
|
130
|
-
o.on '-c', '--concurrency INT', 'Processor threads to use' do |arg|
|
|
131
|
-
opts[:concurrency] = Integer(arg)
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
o.on '-d', '--daemon', 'Daemonize process' do |arg|
|
|
135
|
-
opts[:daemon] = arg
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
o.on '-q', '--queue QUEUE[,WEIGHT]...', 'Queues to process with optional weights' do |arg|
|
|
139
|
-
queue, weight = arg.split(',')
|
|
140
|
-
opts[:queues] = [] unless opts[:queues]
|
|
141
|
-
opts[:queues] << [queue, weight]
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
o.on '-r', '--require [PATH|DIR]', 'Location of the worker' do |arg|
|
|
145
|
-
opts[:require] = arg
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
o.on '-C', '--config PATH', 'Path to YAML config file' do |arg|
|
|
149
|
-
opts[:config_file] = arg
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
o.on '-R', '--rails', 'Load Rails' do |arg|
|
|
153
|
-
opts[:rails] = arg
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
o.on '-L', '--logfile PATH', 'Path to writable logfile' do |arg|
|
|
157
|
-
opts[:logfile] = arg
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
o.on '-P', '--pidfile PATH', 'Path to pidfile' do |arg|
|
|
161
|
-
opts[:pidfile] = arg
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
o.on '-v', '--verbose', 'Print more verbose output' do |arg|
|
|
165
|
-
opts[:verbose] = arg
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
o.on '-V', '--version', 'Print version and exit' do
|
|
169
|
-
puts "Shoryuken #{Shoryuken::VERSION}"
|
|
170
|
-
exit 0
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
@parser.banner = 'shoryuken [options]'
|
|
175
|
-
@parser.on_tail '-h', '--help', 'Show help' do
|
|
176
|
-
logger.info { @parser }
|
|
177
|
-
exit 1
|
|
178
|
-
end
|
|
179
|
-
@parser.parse!(argv)
|
|
180
|
-
opts
|
|
181
|
-
end
|
|
182
|
-
|
|
183
|
-
def handle_signal(sig)
|
|
184
|
-
logger.info { "Got #{sig} signal" }
|
|
185
|
-
|
|
186
|
-
case sig
|
|
187
|
-
when 'USR1'
|
|
188
|
-
logger.info { 'Received USR1, will soft shutdown down' }
|
|
189
|
-
|
|
190
|
-
launcher.stop
|
|
191
|
-
fire_event(:quiet, true)
|
|
192
|
-
exit 0
|
|
193
|
-
when 'TTIN'
|
|
194
|
-
Thread.list.each do |thread|
|
|
195
|
-
logger.info { "Thread TID-#{thread.object_id.to_s(36)} #{thread['label']}" }
|
|
196
|
-
if thread.backtrace
|
|
197
|
-
logger.info { thread.backtrace.join("\n") }
|
|
198
|
-
else
|
|
199
|
-
logger.info { '<no backtrace available>' }
|
|
200
|
-
end
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
ready = launcher.manager.instance_variable_get(:@ready).size
|
|
204
|
-
busy = launcher.manager.instance_variable_get(:@busy).size
|
|
205
|
-
queues = launcher.manager.instance_variable_get(:@queues)
|
|
206
|
-
|
|
207
|
-
logger.info { "Ready: #{ready}, Busy: #{busy}, Active Queues: #{unparse_queues(queues)}" }
|
|
208
|
-
else
|
|
209
|
-
logger.info { "Received #{sig}, will shutdown down" }
|
|
210
|
-
|
|
211
|
-
raise Interrupt
|
|
212
|
-
end
|
|
213
|
-
end
|
|
214
|
-
end
|
|
215
|
-
end
|
data/lib/shoryuken/sns_arn.rb
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
module Shoryuken
|
|
2
|
-
class SnsArn
|
|
3
|
-
def initialize(topic)
|
|
4
|
-
@topic = topic
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def to_s
|
|
8
|
-
@arn ||= "arn:aws:sns:#{region}:#{account_id}:#{@topic}"
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
private
|
|
12
|
-
|
|
13
|
-
def account_id
|
|
14
|
-
Shoryuken::Client.account_id.tap do |account_id|
|
|
15
|
-
if account_id.to_s.empty?
|
|
16
|
-
fail 'To generate SNS ARNs, you must assign an :account_id in your Shoryuken::Client.'
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def region
|
|
22
|
-
Aws.config.fetch(:region) do
|
|
23
|
-
fail 'To generate SNS ARNs, you must include a :region in your AWS config.'
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
data/lib/shoryuken/topic.rb
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
module Shoryuken
|
|
2
|
-
class Topic
|
|
3
|
-
def initialize(name, sns)
|
|
4
|
-
@name, @sns = name, sns
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
def arn
|
|
8
|
-
@arn ||= Client.sns_arn.new(@name).to_s
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def send_message(body, options = {})
|
|
12
|
-
body = JSON.dump(body) if body.is_a?(Hash)
|
|
13
|
-
|
|
14
|
-
@sns.publish(topic_arn: arn, message: body)
|
|
15
|
-
end
|
|
16
|
-
end
|
|
17
|
-
end
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Shoryuken::SnsArn do
|
|
4
|
-
let(:account_id) { '1234567890' }
|
|
5
|
-
let(:region) { 'eu-west-1' }
|
|
6
|
-
let(:topic) { 'topic-x' }
|
|
7
|
-
|
|
8
|
-
before do
|
|
9
|
-
Shoryuken::Client.account_id = account_id
|
|
10
|
-
Aws.config = { region: region }
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
subject { described_class.new(topic).to_s }
|
|
14
|
-
|
|
15
|
-
describe '#to_s' do
|
|
16
|
-
context 'when the Aws config includes all the information necessary' do
|
|
17
|
-
it 'generates an SNS arn' do
|
|
18
|
-
expect(subject).to eq('arn:aws:sns:eu-west-1:1234567890:topic-x')
|
|
19
|
-
end
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
context 'when the Aws config does not include the account id' do
|
|
23
|
-
before do
|
|
24
|
-
Shoryuken::Client.account_id = nil
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it 'fails' do
|
|
28
|
-
expect { subject }.to raise_error(/an :account_id/)
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context 'when the Aws config does not include the region' do
|
|
33
|
-
before do
|
|
34
|
-
Aws.config.delete :region
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
it 'fails' do
|
|
38
|
-
expect { subject }.to raise_error(/a :region/)
|
|
39
|
-
end
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
require 'spec_helper'
|
|
2
|
-
|
|
3
|
-
describe Shoryuken::Topic do
|
|
4
|
-
let(:sns) { Aws::SNS::Client.new stub_responses: true }
|
|
5
|
-
let(:topic_arn) { 'arn:aws:sns:us-east-1:0987654321:shoryuken' }
|
|
6
|
-
let(:topic_name) { 'shoryuken' }
|
|
7
|
-
|
|
8
|
-
before do
|
|
9
|
-
Shoryuken::Client.account_id = '0987654321'
|
|
10
|
-
Aws.config = { region: 'us-east-1' }
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
subject { described_class.new(topic_name, sns) }
|
|
14
|
-
|
|
15
|
-
describe '#send_message' do
|
|
16
|
-
it 'enqueues a message' do
|
|
17
|
-
sns.stub_responses(:publish, { message_id: 'msg1' })
|
|
18
|
-
expect(sns).to receive(:publish).with(topic_arn: topic_arn, message: 'test')
|
|
19
|
-
|
|
20
|
-
subject.send_message('test')
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it 'parses as JSON by default' do
|
|
24
|
-
msg = { field: 'test', other_field: 'other' }
|
|
25
|
-
|
|
26
|
-
sns.stub_responses(:publish, { message_id: 'msg2' })
|
|
27
|
-
expect(sns).to receive(:publish).with(topic_arn: topic_arn, message: JSON.dump(msg))
|
|
28
|
-
|
|
29
|
-
subject.send_message(msg)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|