sneakers 2.3.5 → 2.4.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/.travis.yml +2 -4
- data/Dockerfile +13 -0
- data/Dockerfile.slim +13 -0
- data/LICENSE.txt +1 -1
- data/README.md +24 -0
- data/Rakefile +1 -0
- data/docker-compose.yaml +17 -0
- data/examples/metrics_worker.rb +9 -3
- data/examples/newrelic_metrics_worker.rb +8 -3
- data/examples/title_scraper.rb +18 -5
- data/lib/sneakers.rb +10 -0
- data/lib/sneakers/cli.rb +4 -1
- data/lib/sneakers/configuration.rb +7 -2
- data/lib/sneakers/error_reporter.rb +27 -0
- data/lib/sneakers/handlers/maxretry.rb +1 -1
- data/lib/sneakers/spawner.rb +4 -2
- data/lib/sneakers/version.rb +1 -1
- data/lib/sneakers/worker.rb +7 -15
- data/lib/sneakers/workergroup.rb +7 -1
- data/scripts/local_integration +2 -0
- data/scripts/local_worker +3 -0
- data/sneakers.gemspec +2 -2
- data/spec/fixtures/integration_worker.rb +4 -1
- data/spec/fixtures/require_worker.rb +9 -3
- data/spec/sneakers/integration_spec.rb +6 -3
- data/spec/sneakers/queue_spec.rb +8 -2
- data/spec/sneakers/worker_spec.rb +18 -12
- data/spec/spec_helper.rb +6 -0
- metadata +17 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 681e186272e780e4a969428ad17b2cef7e2f2a17
|
4
|
+
data.tar.gz: e26f11fd1c1282784a2b362d8e263f7b54cb9790
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 33b0a1d5f160771d38b3a8613a8f5b6022709bd1188e73cf2258a130389769bbec744867c76663182b737177718116ed88742e9a61285e61b3b3e4c99ebe2187
|
7
|
+
data.tar.gz: a6d4f4c557c7af9a01863b9b95ab3fd02bf4cb0a6670fe15dcd2e3c0f152839b0dba5a52b67271a83be1044f9b8e80a513f4f365343cc254ee5fb1ab22882719
|
data/.travis.yml
CHANGED
data/Dockerfile
ADDED
data/Dockerfile.slim
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
FROM ruby:2.3-alpine
|
2
|
+
|
3
|
+
RUN apk add --no-cache git
|
4
|
+
ADD . /sneakers
|
5
|
+
WORKDIR /sneakers
|
6
|
+
|
7
|
+
RUN apk --update add --virtual build_deps \
|
8
|
+
build-base ruby-dev libc-dev linux-headers \
|
9
|
+
openssl-dev && \
|
10
|
+
bundle --jobs=4 --retry=3 && \
|
11
|
+
apk del build_deps
|
12
|
+
|
13
|
+
CMD rake test
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Sneakers
|
2
2
|
|
3
|
+
[](https://travis-ci.org/jondot/sneakers)
|
3
4
|
|
4
5
|
```
|
5
6
|
__
|
@@ -153,6 +154,29 @@ Which increments `started` and `handled.ack`, and times the work unit.
|
|
153
154
|
From here, you can continue over to the
|
154
155
|
[Wiki](https://github.com/jondot/sneakers/wiki)
|
155
156
|
|
157
|
+
# Docker
|
158
|
+
|
159
|
+
If you use Docker, there's some benefits to be had and you can use both
|
160
|
+
`docker` and `docker-compose` with this project, in order to run tests,
|
161
|
+
integration tests or a sample worker without setting up RabbitMQ or the
|
162
|
+
environment needed locally on your development box.
|
163
|
+
|
164
|
+
* To build a container run `docker build .`
|
165
|
+
* To run non-integration tests within a docker container, run `docker run --rm
|
166
|
+
sneakers_sneakers:latest`
|
167
|
+
* To run full integration tests within a docker topology including RabbitMQ,
|
168
|
+
Redis (for integration worker) run `scripts/local_integration`, which will
|
169
|
+
use docker-compose to orchestrate the topology and the sneakers Docker image
|
170
|
+
to run the tests
|
171
|
+
* To run a sample worker within Docker, try the `TitleScraper` example by
|
172
|
+
running `script/local_worker`. This will use docker-compose as well. It will
|
173
|
+
also help you get a feeling for how to run Sneakers in a Docker based
|
174
|
+
production environment
|
175
|
+
* User `Dockerfile.slim` instead of `Dockerfile` for production docker builds.
|
176
|
+
It generates a more compact image, while the "regular" `Dockerfile` generates
|
177
|
+
a fatter image - yet faster to iterate when developing
|
178
|
+
|
179
|
+
|
156
180
|
# Compatibility
|
157
181
|
|
158
182
|
* Sneakers 1.1.x and up (using the new generation Bunny 2.x) - Ruby 2.x.x
|
data/Rakefile
CHANGED
data/docker-compose.yaml
ADDED
data/examples/metrics_worker.rb
CHANGED
@@ -3,7 +3,6 @@ require 'sneakers'
|
|
3
3
|
require 'sneakers/runner'
|
4
4
|
require 'sneakers/metrics/logging_metrics'
|
5
5
|
require 'open-uri'
|
6
|
-
require 'nokogiri'
|
7
6
|
|
8
7
|
|
9
8
|
class MetricsWorker
|
@@ -12,10 +11,17 @@ class MetricsWorker
|
|
12
11
|
from_queue 'downloads'
|
13
12
|
|
14
13
|
def work(msg)
|
15
|
-
|
16
|
-
logger.info "FOUND <#{
|
14
|
+
title = extract_title(open(msg))
|
15
|
+
logger.info "FOUND <#{title}>"
|
17
16
|
ack!
|
18
17
|
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def extract_title(html)
|
22
|
+
html =~ /<title>(.*?)<\/title>/
|
23
|
+
$1
|
24
|
+
end
|
19
25
|
end
|
20
26
|
|
21
27
|
|
@@ -3,7 +3,6 @@ require 'sneakers'
|
|
3
3
|
require 'sneakers/runner'
|
4
4
|
require 'sneakers/metrics/newrelic_metrics'
|
5
5
|
require 'open-uri'
|
6
|
-
require 'nokogiri'
|
7
6
|
require 'newrelic_rpm'
|
8
7
|
|
9
8
|
# With this configuration will send two types of data to newrelic server:
|
@@ -22,13 +21,19 @@ class MetricsWorker
|
|
22
21
|
from_queue 'downloads'
|
23
22
|
|
24
23
|
def work(msg)
|
25
|
-
|
26
|
-
logger.info "FOUND <#{
|
24
|
+
title = extract_title(open(msg))
|
25
|
+
logger.info "FOUND <#{title}>"
|
27
26
|
ack!
|
28
27
|
end
|
29
28
|
|
30
29
|
add_transaction_tracer :work, name: 'MetricsWorker', params: 'args[0]'
|
31
30
|
|
31
|
+
private
|
32
|
+
|
33
|
+
def extract_title(html)
|
34
|
+
html =~ /<title>(.*?)<\/title>/
|
35
|
+
$1
|
36
|
+
end
|
32
37
|
end
|
33
38
|
|
34
39
|
|
data/examples/title_scraper.rb
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
require "sneakers"
|
2
2
|
require 'open-uri'
|
3
|
-
require 'nokogiri'
|
4
|
-
|
5
3
|
require 'logger'
|
6
4
|
|
7
|
-
|
5
|
+
def compose_or_localhost(key)
|
6
|
+
Resolv::DNS.new.getaddress(key)
|
7
|
+
rescue
|
8
|
+
"localhost"
|
9
|
+
end
|
10
|
+
|
11
|
+
rmq_addr = compose_or_localhost("rabbitmq")
|
12
|
+
|
13
|
+
Sneakers.configure :log => STDOUT, :amqp => "amqp://guest:guest@#{rmq_addr}:5672"
|
8
14
|
Sneakers.logger.level = Logger::INFO
|
9
15
|
|
10
16
|
class TitleScraper
|
@@ -13,10 +19,17 @@ class TitleScraper
|
|
13
19
|
from_queue 'downloads'
|
14
20
|
|
15
21
|
def work(msg)
|
16
|
-
|
17
|
-
|
22
|
+
title = extract_title(open(msg))
|
23
|
+
logger.info "FOUND <#{title}>"
|
18
24
|
ack!
|
19
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def extract_title(html)
|
30
|
+
html =~ /<title>(.*?)<\/title>/
|
31
|
+
$1
|
32
|
+
end
|
20
33
|
end
|
21
34
|
|
22
35
|
|
data/lib/sneakers.rb
CHANGED
@@ -75,6 +75,16 @@ module Sneakers
|
|
75
75
|
yield self if server?
|
76
76
|
end
|
77
77
|
|
78
|
+
# Register a proc to handle any error which occurs within the Sneakers process.
|
79
|
+
#
|
80
|
+
# Sneakers.error_reporters << proc {|ex,ctx_hash| MyErrorService.notify(ex, ctx_hash) }
|
81
|
+
#
|
82
|
+
# The default error handler logs errors to Sneakers.logger.
|
83
|
+
# Ripped off from https://github.com/mperham/sidekiq/blob/6ad6a3aa330deebd76c6cf0d353f66abd3bef93b/lib/sidekiq.rb#L165-L174
|
84
|
+
def error_reporters
|
85
|
+
CONFIG[:error_reporters]
|
86
|
+
end
|
87
|
+
|
78
88
|
private
|
79
89
|
|
80
90
|
def setup_general_logger!
|
data/lib/sneakers/cli.rb
CHANGED
@@ -25,6 +25,8 @@ module Sneakers
|
|
25
25
|
|
26
26
|
method_option :debug
|
27
27
|
method_option :daemonize
|
28
|
+
method_option :log
|
29
|
+
method_option :pid_path
|
28
30
|
method_option :require
|
29
31
|
|
30
32
|
desc "work FirstWorker,SecondWorker ... ,NthWorker", "Run workers"
|
@@ -33,7 +35,8 @@ module Sneakers
|
|
33
35
|
:daemonize => !!options[:daemonize]
|
34
36
|
}
|
35
37
|
|
36
|
-
opts[:log] =
|
38
|
+
opts[:log] = options[:log] || (opts[:daemonize] ? 'sneakers.log' : STDOUT)
|
39
|
+
opts[:pid_path] = options[:pid_path] if options[:pid_path]
|
37
40
|
|
38
41
|
if opts[:daemonize]
|
39
42
|
puts "*** DEPRACATED: self-daemonization '--daemonize' is considered a bad practice, which is why this feature will be removed in future versions. Please run Sneakers in front, and use things like upstart, systemd, or supervisor to manage it as a daemon."
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'sneakers/error_reporter'
|
1
2
|
require 'forwardable'
|
2
3
|
|
3
4
|
module Sneakers
|
@@ -21,6 +22,10 @@ module Sneakers
|
|
21
22
|
}.freeze
|
22
23
|
|
23
24
|
DEFAULTS = {
|
25
|
+
# Set up default handler which just logs the error.
|
26
|
+
# Remove this in production if you don't want sensitive data logged.
|
27
|
+
:error_reporters => [Sneakers::ErrorReporter::DefaultLogger.new],
|
28
|
+
|
24
29
|
# runner
|
25
30
|
:runner_config_file => nil,
|
26
31
|
:metrics => nil,
|
@@ -29,7 +34,7 @@ module Sneakers
|
|
29
34
|
:workers => 4,
|
30
35
|
:log => STDOUT,
|
31
36
|
:pid_path => 'sneakers.pid',
|
32
|
-
:amqp_heartbeat =>
|
37
|
+
:amqp_heartbeat => 30,
|
33
38
|
|
34
39
|
# workers
|
35
40
|
:timeout_job_after => 5,
|
@@ -37,7 +42,7 @@ module Sneakers
|
|
37
42
|
:threads => 10,
|
38
43
|
:share_threads => false,
|
39
44
|
:ack => true,
|
40
|
-
:heartbeat =>
|
45
|
+
:heartbeat => 30,
|
41
46
|
:hooks => {},
|
42
47
|
:exchange => 'sneakers',
|
43
48
|
:exchange_options => EXCHANGE_OPTION_DEFAULTS,
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# Ripped off from https://github.com/mperham/sidekiq/blob/master/lib/sidekiq/exception_handler.rb
|
2
|
+
module Sneakers
|
3
|
+
module ErrorReporter
|
4
|
+
class DefaultLogger
|
5
|
+
def call(exception, context_hash)
|
6
|
+
Sneakers.logger.warn(context_hash) unless context_hash.empty?
|
7
|
+
log_string = ''
|
8
|
+
log_string += "[Exception error=#{exception.message.inspect} error_class=#{exception.class}" unless exception.nil?
|
9
|
+
log_string += " backtrace=#{exception.backtrace.take(50).join(',')}" unless exception.nil? || exception.backtrace.nil?
|
10
|
+
log_string += ']'
|
11
|
+
Sneakers.logger.error log_string
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def worker_error(exception, context_hash = {})
|
16
|
+
Sneakers.error_reporters.each do |handler|
|
17
|
+
begin
|
18
|
+
handler.call(exception, context_hash)
|
19
|
+
rescue => inner_exception
|
20
|
+
Sneakers.logger.error '!!! ERROR REPORTER THREW AN ERROR !!!'
|
21
|
+
Sneakers.logger.error inner_exception
|
22
|
+
Sneakers.logger.error inner_exception.backtrace.join("\n") unless inner_exception.backtrace.nil?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -140,7 +140,7 @@ module Sneakers
|
|
140
140
|
payload: Base64.encode64(msg.to_s)
|
141
141
|
}.tap do |hash|
|
142
142
|
if reason.is_a?(Exception)
|
143
|
-
hash[:error_class] = reason.class
|
143
|
+
hash[:error_class] = reason.class.to_s
|
144
144
|
hash[:error_message] = "#{reason}"
|
145
145
|
if reason.backtrace
|
146
146
|
hash[:backtrace] = reason.backtrace.take(10).join(', ')
|
data/lib/sneakers/spawner.rb
CHANGED
@@ -13,8 +13,10 @@ module Sneakers
|
|
13
13
|
@exec_string = "bundle exec rake sneakers:run"
|
14
14
|
worker_config = YAML.load(File.read(worker_group_config_file))
|
15
15
|
worker_config.keys.each do |group_name|
|
16
|
+
workers = worker_config[group_name]['classes']
|
17
|
+
workers = workers.join "," if workers.is_a?(Array)
|
16
18
|
@pids << fork do
|
17
|
-
@exec_hash = {"WORKERS"=>
|
19
|
+
@exec_hash = {"WORKERS"=> workers, "WORKER_COUNT" => worker_config[group_name]["workers"].to_s}
|
18
20
|
Kernel.exec(@exec_hash, @exec_string)
|
19
21
|
end
|
20
22
|
end
|
@@ -24,4 +26,4 @@ module Sneakers
|
|
24
26
|
Process.waitall
|
25
27
|
end
|
26
28
|
end
|
27
|
-
end
|
29
|
+
end
|
data/lib/sneakers/version.rb
CHANGED
data/lib/sneakers/worker.rb
CHANGED
@@ -10,6 +10,7 @@ module Sneakers
|
|
10
10
|
# (because it uses methods from them directly.)
|
11
11
|
include Concerns::Logging
|
12
12
|
include Concerns::Metrics
|
13
|
+
include Sneakers::ErrorReporter
|
13
14
|
|
14
15
|
def initialize(queue = nil, pool = nil, opts = {})
|
15
16
|
opts = opts.merge(self.class.queue_opts || {})
|
@@ -59,13 +60,13 @@ module Sneakers
|
|
59
60
|
end
|
60
61
|
end
|
61
62
|
end
|
62
|
-
rescue Timeout::Error
|
63
|
+
rescue Timeout::Error => ex
|
63
64
|
res = :timeout
|
64
|
-
worker_error(
|
65
|
+
worker_error(ex, log_msg: log_msg(msg), message: msg)
|
65
66
|
rescue => ex
|
66
67
|
res = :error
|
67
68
|
error = ex
|
68
|
-
worker_error(
|
69
|
+
worker_error(ex, log_msg: log_msg(msg), message: msg)
|
69
70
|
end
|
70
71
|
|
71
72
|
if @should_ack
|
@@ -92,6 +93,8 @@ module Sneakers
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def stop
|
96
|
+
worker_trace "Stopping worker: shutting down thread pool."
|
97
|
+
@pool.shutdown
|
95
98
|
worker_trace "Stopping worker: unsubscribing."
|
96
99
|
@queue.unsubscribe
|
97
100
|
worker_trace "Stopping worker: I'm gone."
|
@@ -108,17 +111,6 @@ module Sneakers
|
|
108
111
|
"[#{@id}][#{Thread.current}][#{@queue.name}][#{@queue.opts}] #{msg}"
|
109
112
|
end
|
110
113
|
|
111
|
-
# Helper to log an error message with an optional exception
|
112
|
-
def worker_error(msg, exception = nil)
|
113
|
-
s = log_msg(msg)
|
114
|
-
if exception
|
115
|
-
s += " [Exception error=#{exception.message.inspect} error_class=#{exception.class}"
|
116
|
-
s += " backtrace=#{exception.backtrace.take(50).join(',')}" unless exception.backtrace.nil?
|
117
|
-
s += "]"
|
118
|
-
end
|
119
|
-
logger.error(s)
|
120
|
-
end
|
121
|
-
|
122
114
|
def worker_trace(msg)
|
123
115
|
logger.debug(log_msg(msg))
|
124
116
|
end
|
@@ -146,7 +138,7 @@ module Sneakers
|
|
146
138
|
private
|
147
139
|
|
148
140
|
def publisher
|
149
|
-
@publisher ||= Sneakers::Publisher.new
|
141
|
+
@publisher ||= Sneakers::Publisher.new(queue_opts)
|
150
142
|
end
|
151
143
|
end
|
152
144
|
end
|
data/lib/sneakers/workergroup.rb
CHANGED
@@ -23,7 +23,13 @@ module Sneakers
|
|
23
23
|
# when used with many workers.
|
24
24
|
pool = config[:share_threads] ? Thread.pool(config[:threads]) : nil
|
25
25
|
|
26
|
-
|
26
|
+
worker_classes = config[:worker_classes]
|
27
|
+
|
28
|
+
if worker_classes.respond_to? :call
|
29
|
+
worker_classes = worker_classes.call
|
30
|
+
end
|
31
|
+
|
32
|
+
@workers = worker_classes.map{|w| w.new(nil, pool) }
|
27
33
|
# if more than one worker this should be per worker
|
28
34
|
# accumulate clients and consumers as well
|
29
35
|
@workers.each do |worker|
|
data/sneakers.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |gem|
|
|
18
18
|
gem.test_files = gem.files.grep(/^(test|spec|features)\//)
|
19
19
|
gem.require_paths = ['lib']
|
20
20
|
gem.add_dependency 'serverengine', '~> 1.5.11'
|
21
|
-
gem.add_dependency 'bunny', '~> 2.
|
21
|
+
gem.add_dependency 'bunny', '~> 2.6'
|
22
22
|
gem.add_dependency 'thread', '~> 0.1.7'
|
23
23
|
gem.add_dependency 'thor'
|
24
24
|
|
@@ -27,8 +27,8 @@ Gem::Specification.new do |gem|
|
|
27
27
|
gem.add_development_dependency 'redis'
|
28
28
|
|
29
29
|
gem.add_development_dependency 'rr'
|
30
|
+
gem.add_development_dependency 'unparser', '0.2.2' # keep below 0.2.5 for ruby 2.0 compat.
|
30
31
|
gem.add_development_dependency 'ruby-prof'
|
31
|
-
gem.add_development_dependency 'nokogiri'
|
32
32
|
gem.add_development_dependency 'guard-minitest'
|
33
33
|
gem.add_development_dependency 'metric_fu'
|
34
34
|
gem.add_development_dependency 'simplecov'
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'sneakers'
|
2
2
|
require 'open-uri'
|
3
|
-
require 'nokogiri'
|
4
3
|
|
5
4
|
|
6
5
|
class TitleScraper
|
@@ -9,9 +8,16 @@ class TitleScraper
|
|
9
8
|
from_queue 'downloads'
|
10
9
|
|
11
10
|
def work(msg)
|
12
|
-
|
13
|
-
|
11
|
+
title = extract_title(open(msg))
|
12
|
+
logger.info "FOUND <#{title}>"
|
14
13
|
ack!
|
15
14
|
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def extract_title(html)
|
19
|
+
html =~ /<title>(.*?)<\/title>/
|
20
|
+
$1
|
21
|
+
end
|
16
22
|
end
|
17
23
|
|
@@ -20,8 +20,10 @@ describe "integration" do
|
|
20
20
|
def prepare
|
21
21
|
# clean up all integration queues; admin interface must be installed
|
22
22
|
# in integration env
|
23
|
+
rmq_addr = compose_or_localhost("rabbitmq")
|
24
|
+
puts "RABBITMQ is at #{rmq_addr}"
|
23
25
|
begin
|
24
|
-
admin = RabbitMQ::HTTP::Client.new("http
|
26
|
+
admin = RabbitMQ::HTTP::Client.new("http://#{rmq_addr}:15672/", username: "guest", password: "guest")
|
25
27
|
qs = admin.list_queues
|
26
28
|
qs.each do |q|
|
27
29
|
name = q.name
|
@@ -35,13 +37,14 @@ describe "integration" do
|
|
35
37
|
end
|
36
38
|
|
37
39
|
Sneakers.clear!
|
38
|
-
Sneakers.configure
|
40
|
+
Sneakers.configure(:amqp => "amqp://guest:guest@#{rmq_addr}:5672")
|
39
41
|
Sneakers.logger.level = Logger::ERROR
|
40
42
|
|
41
43
|
# configure integration worker on a random generated queue
|
42
44
|
random_queue = "integration_#{rand(10**36).to_s(36)}"
|
43
45
|
|
44
|
-
|
46
|
+
redis_addr = compose_or_localhost("redis")
|
47
|
+
@redis = Redis.new(:host => redis_addr)
|
45
48
|
@redis.del(random_queue)
|
46
49
|
IntegrationWorker.from_queue(random_queue)
|
47
50
|
end
|
data/spec/sneakers/queue_spec.rb
CHANGED
@@ -38,7 +38,10 @@ describe Sneakers::Queue do
|
|
38
38
|
|
39
39
|
mock(@mkbunny).start {}
|
40
40
|
mock(@mkbunny).create_channel{ @mkchan }
|
41
|
-
mock(Bunny).new(
|
41
|
+
mock(Bunny).new(
|
42
|
+
anything,
|
43
|
+
hash_including(:vhost => '/', :heartbeat => 2)
|
44
|
+
){ @mkbunny }
|
42
45
|
end
|
43
46
|
|
44
47
|
describe "#subscribe with sneakers exchange" do
|
@@ -101,7 +104,10 @@ describe Sneakers::Queue do
|
|
101
104
|
before do
|
102
105
|
# expect default exchange
|
103
106
|
queue_vars[:exchange] = ""
|
104
|
-
mock(@mkchan).exchange("",
|
107
|
+
mock(@mkchan).exchange("",
|
108
|
+
:type => :direct,
|
109
|
+
:durable => true,
|
110
|
+
:arguments => {"x-arg" => "value"}){ @mkex }
|
105
111
|
end
|
106
112
|
|
107
113
|
it "does not bind to exchange" do
|
@@ -2,7 +2,6 @@ require 'spec_helper'
|
|
2
2
|
require 'sneakers'
|
3
3
|
require 'timeout'
|
4
4
|
|
5
|
-
|
6
5
|
class DummyWorker
|
7
6
|
include Sneakers::Worker
|
8
7
|
from_queue 'downloads',
|
@@ -167,9 +166,12 @@ describe Sneakers::Worker do
|
|
167
166
|
msg.must_equal(message)
|
168
167
|
opts.must_equal(:to_queue => "defaults")
|
169
168
|
end
|
169
|
+
end
|
170
170
|
|
171
|
-
|
172
|
-
|
171
|
+
it "passes the configuration to the publisher" do
|
172
|
+
opts = DummyWorker.queue_opts
|
173
|
+
mock(Sneakers::Publisher).new(opts) { mock(Object.new).publish(anything, anything) }
|
174
|
+
DummyWorker.enqueue(message)
|
173
175
|
end
|
174
176
|
end
|
175
177
|
|
@@ -179,6 +181,7 @@ describe Sneakers::Worker do
|
|
179
181
|
@defaults_q = DefaultsWorker.new.queue
|
180
182
|
@defaults_q.name.must_equal('defaults')
|
181
183
|
@defaults_q.opts.to_hash.must_equal(
|
184
|
+
:error_reporters => [Sneakers.error_reporters.last],
|
182
185
|
:runner_config_file => nil,
|
183
186
|
:metrics => nil,
|
184
187
|
:daemonize => true,
|
@@ -208,8 +211,8 @@ describe Sneakers::Worker do
|
|
208
211
|
},
|
209
212
|
:hooks => {},
|
210
213
|
:handler => Sneakers::Handlers::Oneshot,
|
211
|
-
:heartbeat =>
|
212
|
-
:amqp_heartbeat =>
|
214
|
+
:heartbeat => 30,
|
215
|
+
:amqp_heartbeat => 30
|
213
216
|
)
|
214
217
|
end
|
215
218
|
|
@@ -217,6 +220,7 @@ describe Sneakers::Worker do
|
|
217
220
|
@dummy_q = DummyWorker.new.queue
|
218
221
|
@dummy_q.name.must_equal('downloads')
|
219
222
|
@dummy_q.opts.to_hash.must_equal(
|
223
|
+
:error_reporters => [Sneakers.error_reporters.last],
|
220
224
|
:runner_config_file => nil,
|
221
225
|
:metrics => nil,
|
222
226
|
:daemonize => true,
|
@@ -247,7 +251,7 @@ describe Sneakers::Worker do
|
|
247
251
|
:hooks => {},
|
248
252
|
:handler => Sneakers::Handlers::Oneshot,
|
249
253
|
:heartbeat => 5,
|
250
|
-
:amqp_heartbeat =>
|
254
|
+
:amqp_heartbeat => 30
|
251
255
|
)
|
252
256
|
end
|
253
257
|
|
@@ -255,6 +259,7 @@ describe Sneakers::Worker do
|
|
255
259
|
@deprecated_exchange_opts_q = WithDeprecatedExchangeOptionsWorker.new.queue
|
256
260
|
@deprecated_exchange_opts_q.name.must_equal('defaults')
|
257
261
|
@deprecated_exchange_opts_q.opts.to_hash.must_equal(
|
262
|
+
:error_reporters => [Sneakers.error_reporters.last],
|
258
263
|
:runner_config_file => nil,
|
259
264
|
:metrics => nil,
|
260
265
|
:daemonize => true,
|
@@ -284,8 +289,8 @@ describe Sneakers::Worker do
|
|
284
289
|
},
|
285
290
|
:hooks => {},
|
286
291
|
:handler => Sneakers::Handlers::Oneshot,
|
287
|
-
:heartbeat =>
|
288
|
-
:amqp_heartbeat =>
|
292
|
+
:heartbeat => 30,
|
293
|
+
:amqp_heartbeat => 30
|
289
294
|
)
|
290
295
|
end
|
291
296
|
end
|
@@ -334,7 +339,7 @@ describe Sneakers::Worker do
|
|
334
339
|
handler = Object.new
|
335
340
|
header = Object.new
|
336
341
|
mock(handler).error(header, nil, "msg", anything)
|
337
|
-
mock(w.logger).error(
|
342
|
+
mock(w.logger).error(/\[Exception error="foo" error_class=RuntimeError backtrace=.*/)
|
338
343
|
w.do_work(header, nil, "msg", handler)
|
339
344
|
end
|
340
345
|
|
@@ -356,7 +361,7 @@ describe Sneakers::Worker do
|
|
356
361
|
header = Object.new
|
357
362
|
|
358
363
|
mock(handler).timeout(header, nil, "msg")
|
359
|
-
mock(w.logger).error(/
|
364
|
+
mock(w.logger).error(/error="execution expired" error_class=Timeout::Error backtrace=/)
|
360
365
|
|
361
366
|
w.do_work(header, nil, "msg", handler)
|
362
367
|
end
|
@@ -454,8 +459,9 @@ describe Sneakers::Worker do
|
|
454
459
|
describe '#worker_error' do
|
455
460
|
it 'only logs backtraces if present' do
|
456
461
|
w = DummyWorker.new(@queue, TestPool.new)
|
457
|
-
mock(w.logger).
|
458
|
-
w.
|
462
|
+
mock(w.logger).warn('cuz')
|
463
|
+
mock(w.logger).error(/\[Exception error="boom!" error_class=RuntimeError\]/)
|
464
|
+
w.worker_error(RuntimeError.new('boom!'), 'cuz')
|
459
465
|
end
|
460
466
|
end
|
461
467
|
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'bundler/setup'
|
2
2
|
require 'simplecov'
|
3
|
+
require 'resolv'
|
3
4
|
SimpleCov.start do
|
4
5
|
add_filter "/spec/"
|
5
6
|
end
|
@@ -8,6 +9,11 @@ require 'minitest/autorun'
|
|
8
9
|
|
9
10
|
require 'rr'
|
10
11
|
|
12
|
+
def compose_or_localhost(key)
|
13
|
+
Resolv::DNS.new.getaddress(key)
|
14
|
+
rescue
|
15
|
+
"localhost"
|
16
|
+
end
|
11
17
|
|
12
18
|
|
13
19
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sneakers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dotan Nahum
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-11-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: serverengine
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.
|
33
|
+
version: '2.6'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.
|
40
|
+
version: '2.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: thread
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -109,21 +109,21 @@ dependencies:
|
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
112
|
+
name: unparser
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
|
-
- -
|
115
|
+
- - '='
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
117
|
+
version: 0.2.2
|
118
118
|
type: :development
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
|
-
- -
|
122
|
+
- - '='
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
124
|
+
version: 0.2.2
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
126
|
+
name: ruby-prof
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
128
128
|
requirements:
|
129
129
|
- - ">="
|
@@ -244,6 +244,8 @@ extra_rdoc_files: []
|
|
244
244
|
files:
|
245
245
|
- ".gitignore"
|
246
246
|
- ".travis.yml"
|
247
|
+
- Dockerfile
|
248
|
+
- Dockerfile.slim
|
247
249
|
- Gemfile
|
248
250
|
- Guardfile
|
249
251
|
- LICENSE.txt
|
@@ -251,6 +253,7 @@ files:
|
|
251
253
|
- ROADMAP.md
|
252
254
|
- Rakefile
|
253
255
|
- bin/sneakers
|
256
|
+
- docker-compose.yaml
|
254
257
|
- examples/benchmark_worker.rb
|
255
258
|
- examples/max_retry_handler.rb
|
256
259
|
- examples/metrics_worker.rb
|
@@ -264,6 +267,7 @@ files:
|
|
264
267
|
- lib/sneakers/concerns/logging.rb
|
265
268
|
- lib/sneakers/concerns/metrics.rb
|
266
269
|
- lib/sneakers/configuration.rb
|
270
|
+
- lib/sneakers/error_reporter.rb
|
267
271
|
- lib/sneakers/handlers/maxretry.rb
|
268
272
|
- lib/sneakers/handlers/oneshot.rb
|
269
273
|
- lib/sneakers/metrics/logging_metrics.rb
|
@@ -280,6 +284,8 @@ files:
|
|
280
284
|
- lib/sneakers/version.rb
|
281
285
|
- lib/sneakers/worker.rb
|
282
286
|
- lib/sneakers/workergroup.rb
|
287
|
+
- scripts/local_integration
|
288
|
+
- scripts/local_worker
|
283
289
|
- sneakers.gemspec
|
284
290
|
- spec/fixtures/integration_worker.rb
|
285
291
|
- spec/fixtures/require_worker.rb
|
@@ -315,7 +321,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
315
321
|
version: '0'
|
316
322
|
requirements: []
|
317
323
|
rubyforge_project:
|
318
|
-
rubygems_version: 2.
|
324
|
+
rubygems_version: 2.5.1
|
319
325
|
signing_key:
|
320
326
|
specification_version: 4
|
321
327
|
summary: Fast background processing framework for Ruby and RabbitMQ
|