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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b0d4672a260de0253f534bfd74c49588df84d56
4
- data.tar.gz: e8d4eee7b40b2624b2fb99f24a210305d9dff64a
3
+ metadata.gz: 681e186272e780e4a969428ad17b2cef7e2f2a17
4
+ data.tar.gz: e26f11fd1c1282784a2b362d8e263f7b54cb9790
5
5
  SHA512:
6
- metadata.gz: da994869c06cc5c0fdb8d12c7c3b23f3969ab93db70200d7ffdf67ff4001d7aedc86eb2587ff11a7152683fb87222f500827c7f70bc2c42496eac7b22dc03b77
7
- data.tar.gz: fc60b50180bb952c197c3bf553cb9fff63db09bb8bdd86a5dbf7335cce2ef49ba01ea669276601023b56379f2d97bcdc3d3a027490402c8781a8b7073b58f234
6
+ metadata.gz: 33b0a1d5f160771d38b3a8613a8f5b6022709bd1188e73cf2258a130389769bbec744867c76663182b737177718116ed88742e9a61285e61b3b3e4c99ebe2187
7
+ data.tar.gz: a6d4f4c557c7af9a01863b9b95ab3fd02bf4cb0a6670fe15dcd2e3c0f152839b0dba5a52b67271a83be1044f9b8e80a513f4f365343cc254ee5fb1ab22882719
data/.travis.yml CHANGED
@@ -6,12 +6,10 @@ cache: bundler
6
6
  language: ruby
7
7
  rvm:
8
8
  - ruby-head
9
- - 2.2
10
- - 2.1
11
- - 2.0.0
9
+ - 2.2.5
12
10
  matrix:
13
11
  include:
14
- - rvm: 2.2
12
+ - rvm: 2.2.5
15
13
  env: INTEGRATION_LOG=1 INTEGRATION=1
16
14
 
17
15
 
data/Dockerfile ADDED
@@ -0,0 +1,13 @@
1
+ FROM ruby:2.3-alpine
2
+
3
+ RUN apk add --no-cache git
4
+ RUN apk --update add --virtual build_deps \
5
+ build-base ruby-dev libc-dev linux-headers \
6
+ openssl-dev
7
+
8
+ ADD . /sneakers
9
+ WORKDIR /sneakers
10
+
11
+ RUN bundle --jobs=4 --retry=3
12
+
13
+ CMD rake test
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
@@ -1,4 +1,4 @@
1
- Copyright (c) 2013-2014 Dotan Nahum
1
+ Copyright (c) 2013-2016 Dotan Nahum
2
2
 
3
3
  MIT License
4
4
 
data/README.md CHANGED
@@ -1,5 +1,6 @@
1
1
  # Sneakers
2
2
 
3
+ [![Build Status](https://travis-ci.org/jondot/sneakers.svg?branch=master)](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
@@ -5,6 +5,7 @@ require 'rake/testtask'
5
5
  Rake::TestTask.new do |t|
6
6
  t.libs << "spec"
7
7
  t.test_files = FileList['spec/**/*_spec.rb']
8
+ t.warning = false
8
9
  end
9
10
 
10
11
  task default: :test
@@ -0,0 +1,17 @@
1
+ version: '2'
2
+ services:
3
+ sneakers:
4
+ build: .
5
+ depends_on:
6
+ - rabbitmq
7
+ - redis
8
+ rabbitmq:
9
+ image: rabbitmq:management
10
+ ports:
11
+ - "5672:5672"
12
+ - "15672:15672"
13
+ redis:
14
+ image: redis
15
+ ports:
16
+ - "6379:6379"
17
+
@@ -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
- doc = Nokogiri::HTML(open(msg))
16
- logger.info "FOUND <#{doc.css('title').text}>"
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
- doc = Nokogiri::HTML(open(msg))
26
- logger.info "FOUND <#{doc.css('title').text}>"
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
 
@@ -1,10 +1,16 @@
1
1
  require "sneakers"
2
2
  require 'open-uri'
3
- require 'nokogiri'
4
-
5
3
  require 'logger'
6
4
 
7
- Sneakers.configure :log => STDOUT
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
- doc = Nokogiri::HTML(open(msg))
17
- worker_trace "FOUND <#{doc.css('title').text}>"
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] = opts[:daemonize] ? 'sneakers.log' : STDOUT
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 => 10,
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 => 2,
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(', ')
@@ -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"=> worker_config[group_name]['classes'], "WORKER_COUNT" => worker_config[group_name]["workers"].to_s}
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
@@ -1,3 +1,3 @@
1
1
  module Sneakers
2
- VERSION = "2.3.5"
2
+ VERSION = "2.4.0"
3
3
  end
@@ -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('timeout')
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('unexpected error', ex)
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
@@ -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
- @workers = config[:worker_classes].map{|w| w.new(nil, pool) }
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|
@@ -0,0 +1,2 @@
1
+ #!/bin/sh
2
+ docker-compose run -e INTEGRATION=1 -e INTEGRATION_LOG=1 sneakers rake test
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+ docker-compose run sneakers sneakers work TitleScraper --require examples/title_scraper.rb
3
+
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.2.0'
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'
@@ -2,7 +2,10 @@ require 'sneakers'
2
2
  require 'thread'
3
3
  require 'redis'
4
4
 
5
- $redis = Redis.new
5
+
6
+ redis_addr = compose_or_localhost("redis")
7
+ puts "REDIS is at #{redis_addr}"
8
+ $redis = Redis.new(:host => redis_addr)
6
9
 
7
10
  class IntegrationWorker
8
11
  include Sneakers::Worker
@@ -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
- doc = Nokogiri::HTML(open(msg))
13
- worker_trace "FOUND <#{doc.css('title').text}>"
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://127.0.0.1:15672/", username: "guest", password: "guest")
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
- @redis = Redis.new
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
@@ -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(anything, :vhost => '/', :heartbeat => 2){ @mkbunny }
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("", :type => :direct, :durable => true){ @mkex }
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
- stub(Sneakers::Publisher).new { mock }
172
- DefaultsWorker.enqueue(message)
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 => 2,
212
- :amqp_heartbeat => 10
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 => 10
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 => 2,
288
- :amqp_heartbeat => 10
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(/unexpected error \[Exception error="foo" error_class=RuntimeError backtrace=.*/)
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(/timeout/)
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).error(/cuz \[Exception error="boom!" error_class=RuntimeError\]/)
458
- w.worker_error('cuz', RuntimeError.new('boom!'))
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.3.5
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: 2015-10-13 00:00:00.000000000 Z
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.2.0
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.2.0
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: ruby-prof
112
+ name: unparser
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - ">="
115
+ - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: '0'
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: '0'
124
+ version: 0.2.2
125
125
  - !ruby/object:Gem::Dependency
126
- name: nokogiri
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.4.5.1
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