sneakers 2.7.0 → 2.11.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: '09f8536528b4fa33c1d597f1ca8f513d5ca8f37b'
4
- data.tar.gz: c24a191dc06d4457c9f5ac7bfd8f089ca7ed175f
3
+ metadata.gz: b012bf95d1ffd483c544a1e58a11775dd1932726
4
+ data.tar.gz: 5df9669b11a6870968f08483ae1d4bef08becbeb
5
5
  SHA512:
6
- metadata.gz: 8e24898e348b40e79640d216fa9c56b63bf8c94340f23b4e54a4a163fdcbee8c7628a3db7f3128d3ed0220e9e7f83b36239917e610a9ca5b9c481108847cc61c
7
- data.tar.gz: 369b932fef00b62847c74e070cd6248203505bf87ff3d932de8eb9ef80bcd65dd7732d59f7b47def85b4746c4b9cce0e933c0bb0b6845fe2f40f8f6a33b8e07b
6
+ metadata.gz: 9875ccd366feeb446faaf1c7d9b2aceb8fd3712aaf67e989329eba05ee4c4dc45e0cc5df718a399eeb7302c924b2d131491db75ce9bb824162ae94a734872889
7
+ data.tar.gz: 7e6e444e6801cc7ddf4bbbfcd197efe6633cda6f004bce71759414aef978669ae1b29136c9135621fffe4b40986546fe237c9b9dd4d6298862416ff5042f97e1
data/.gitignore CHANGED
@@ -8,3 +8,4 @@ tmp/
8
8
  .ruby-version
9
9
  .ruby-gemset
10
10
  .bundle/*
11
+ *.gem
@@ -4,14 +4,15 @@ services:
4
4
  sudo: false
5
5
  cache: bundler
6
6
  language: ruby
7
+ before_install:
8
+ - gem install bundler
7
9
  rvm:
8
10
  - ruby-head
9
- - "2.4.1"
10
- - "2.3.4"
11
- - "2.2.7"
11
+ - "2.5.1"
12
+ - "2.4.2"
13
+ - "2.3.5"
14
+ - "2.2.8"
12
15
  matrix:
13
16
  include:
14
- - rvm: 2.2.5
17
+ - rvm: 2.4.1
15
18
  env: INTEGRATION_LOG=1 INTEGRATION=1
16
-
17
-
@@ -1,5 +1,66 @@
1
1
  # Sneakers Change Log
2
2
 
3
+ ## Changes Between 2.10.0 and 2.11.0
4
+
5
+ This releases includes bug fixes, support for more queue-binding options, better
6
+ management of the Bunny dependency, and improved documentation. Following is a
7
+ list of the notable changes:
8
+
9
+ ### Rescue from ScriptError
10
+
11
+ Fixes a bug that would cause Sneakers workers to freeze if an exception
12
+ descending from `ScriptError`, such as `NotImplementedError`, is raised
13
+
14
+ Contributed by @sharshenov
15
+
16
+ GitHub Pull Request: [373](https://github.com/jondot/sneakers/pull/373)
17
+
18
+ ### Loosen Bunny dependency to minor version
19
+
20
+ The dependency on Bunny is now pinned to the minor version instead of patch,
21
+ allowing users to benefit from non-breaking updates to Bunny without having to
22
+ wait for a Sneakers release.
23
+
24
+ Contributed by @olivierlacan
25
+
26
+ GitHub Pull Request: [#372](https://github.com/jondot/sneakers/pull/372)
27
+
28
+ ### Support `:bind_arguments` on bind
29
+
30
+ It is now possible to set arguments on a queue when connecting to a headers
31
+ exchange
32
+
33
+ Contributed by @nerikj
34
+
35
+ GitHub Pull Request: [#358](https://github.com/jondot/sneakers/pull/358)
36
+
37
+ ### Other contributions
38
+
39
+ This release also contains contributions from @ivan-kolmychek (bumping up Bunny
40
+ dependency), @michaelklishin (improving code style), and @darren987469 (adding
41
+ examples to the README)
42
+
43
+ ## Changes Between 2.8.0 and 2.10.0
44
+
45
+ This release contains **minor breaking API changes**.
46
+
47
+ ### Worker Timeouts are No Longer Enforced
48
+
49
+ This is a **breaking change** for `Sneakers::Worker` implementations.
50
+
51
+ Timeouts can be disruptive and dangerous depending on what the workers do but not having them can also
52
+ lead to operational headaches.
53
+
54
+ The outcome of [a lengthy discussion](https://github.com/jondot/sneakers/issues/343) on possible
55
+ alternatives to the timeout mechanisms is that only applications
56
+ can know where it is safe to enforce a timeout (and how).
57
+
58
+ `Sneakers::Worker` implementations are now expected to enforce timeouts
59
+ in a way that makes sense (and is safe) to them.
60
+
61
+ GitHub issues: [#343](https://github.com/jondot/sneakers/issues/343).
62
+
63
+
3
64
  ## Changes Between 2.6.0 and 2.7.0
4
65
 
5
66
  This release requires Ruby 2.2 and has **breaking API changes**
data/Dockerfile CHANGED
@@ -1,13 +1,28 @@
1
1
  FROM ruby:2.3-alpine
2
2
 
3
3
  RUN apk add --no-cache git
4
+
4
5
  RUN apk --update add --virtual build_deps \
5
- build-base ruby-dev libc-dev linux-headers \
6
- openssl-dev
6
+ build-base \
7
+ ruby-dev \
8
+ libc-dev \
9
+ linux-headers \
10
+ openssl-dev
11
+
12
+ RUN mkdir /myapp
7
13
 
8
- ADD . /sneakers
9
14
  WORKDIR /sneakers
10
15
 
16
+ COPY lib/sneakers/version.rb /sneakers/lib/sneakers/version.rb
17
+
18
+ COPY sneakers.gemspec /sneakers/sneakers.gemspec
19
+
20
+ COPY Gemfile /sneakers/Gemfile
21
+
22
+ COPY Gemfile.lock /sneakers/Gemfile.lock
23
+
11
24
  RUN bundle --jobs=4 --retry=3
12
25
 
26
+ COPY . /sneakers
27
+
13
28
  CMD rake test
@@ -1,13 +1,20 @@
1
1
  FROM ruby:2.3-alpine
2
2
 
3
3
  RUN apk add --no-cache git
4
+
4
5
  ADD . /sneakers
6
+
5
7
  WORKDIR /sneakers
6
8
 
7
9
  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
10
+ build-base \
11
+ ruby-dev \
12
+ libc-dev \
13
+ linux-headers \
14
+ openssl-dev && \
15
+
16
+ bundle --jobs=4 --retry=3 && \
17
+
18
+ apk del build_deps
12
19
 
13
20
  CMD rake test
data/README.md CHANGED
@@ -4,47 +4,47 @@
4
4
 
5
5
  ```
6
6
  __
7
- ,--' >
8
- `=====
7
+ ,--' >
8
+ `=====
9
9
 
10
10
  ```
11
11
 
12
-
13
12
  A high-performance RabbitMQ background processing framework for
14
13
  Ruby.
15
14
 
16
-
17
15
  Sneakers is being used in production for both I/O and CPU intensive workloads, and have achieved the goals of high-performance and 0-maintenance, as designed.
18
16
 
19
-
20
- Visit the [wiki](https://github.com/jondot/sneakers/wiki) for
21
- documentation and [GitHub releases](https://github.com/jondot/sneakers/releases) for release
22
- notes.
23
-
24
- [![Build Status](https://travis-ci.org/jondot/sneakers.svg?branch=master)](https://travis-ci.org/jondot/sneakers)
25
-
26
-
27
17
  ## Installation
28
18
 
29
19
  Add this line to your application's Gemfile:
30
20
 
31
- ``` ruby
21
+ ```ruby
32
22
  gem 'sneakers'
33
23
  ```
34
24
 
35
25
  And then execute:
36
26
 
37
- ``` shell-session
27
+ ```shell-session
38
28
  $ bundle
39
29
  ```
40
30
 
41
31
  Or install it yourself as:
42
32
 
43
- ``` shell-session
33
+ ```shell-session
44
34
  $ gem install sneakers
45
35
  ```
46
36
 
47
- ## Quick start
37
+ ## Documentation
38
+
39
+ A quick start guide is available in the section below.
40
+
41
+ Visit the [wiki](https://github.com/jondot/sneakers/wiki) for more detailed
42
+ documentation and [GitHub releases](https://github.com/jondot/sneakers/releases) for release
43
+ notes.
44
+
45
+ A [change log](./ChangeLog.md) is also available.
46
+
47
+ ## Quick start
48
48
 
49
49
  Set up a Gemfile
50
50
 
@@ -60,7 +60,6 @@ then create a worker named as `Processor`.
60
60
 
61
61
  > touch boot.rb
62
62
 
63
-
64
63
  ```ruby
65
64
  require 'sneakers'
66
65
  require 'redis'
@@ -86,7 +85,6 @@ end
86
85
 
87
86
  Let's test it out quickly from the command line:
88
87
 
89
-
90
88
  ```shell-session
91
89
  $ sneakers work Processor --require boot.rb
92
90
  ```
@@ -103,6 +101,20 @@ If you go to your RabbitMQ admin now, you'll see a new queue named `logs` was cr
103
101
  }
104
102
  ```
105
103
 
104
+ Publish a message with the [bunny](https://github.com/ruby-amqp/bunny) gem RabbitMQ client:
105
+
106
+ ```ruby
107
+ require 'bunny'
108
+
109
+ conn = Bunny.new
110
+ conn.start
111
+
112
+ ch = conn.create_channel
113
+ ch.default_exchange.publish({ type: 'error', message: 'HALP!', error: 'CODE001' }.to_json, routing_key: 'logs')
114
+
115
+ conn.close
116
+ ```
117
+
106
118
  And this is the output you should see at your terminal.
107
119
 
108
120
  ```
@@ -112,7 +124,6 @@ And this is the output you should see at your terminal.
112
124
  2013-10-11T19:26:40Z p-4719 t-ovqgyrx8g INFO: log log
113
125
  ```
114
126
 
115
-
116
127
  We'll count errors and error types with Redis.
117
128
 
118
129
  ``` shell-session
@@ -120,11 +131,8 @@ $ redis-cli monitor
120
131
  1381520329.888581 [0 127.0.0.1:49182] "incr" "processor:CODE001"
121
132
  ```
122
133
 
123
-
124
134
  We're basically done with the ceremonies and all is left is to do some real work.
125
135
 
126
-
127
-
128
136
  ### Looking at metrics
129
137
 
130
138
  Let's use the `logging_metrics` provider just for the sake of fun of seeing the metrics as they happen.
@@ -135,7 +143,7 @@ require 'sneakers'
135
143
  require 'redis'
136
144
  require 'json'
137
145
  require 'sneakers/metrics/logging_metrics'
138
- Sneakers.configure :metrics => Sneakers::Metrics::LoggingMetrics.new
146
+ Sneakers.configure(metrics: Sneakers::Metrics::LoggingMetrics.new)
139
147
 
140
148
  # ... rest of code
141
149
  ```
@@ -150,7 +158,6 @@ Now push a message again and you'll see:
150
158
 
151
159
  Which increments `started` and `handled.ack`, and times the work unit.
152
160
 
153
-
154
161
  From here, you can continue over to the
155
162
  [Wiki](https://github.com/jondot/sneakers/wiki)
156
163
 
@@ -161,7 +168,7 @@ If you use Docker, there's some benefits to be had and you can use both
161
168
  integration tests or a sample worker without setting up RabbitMQ or the
162
169
  environment needed locally on your development box.
163
170
 
164
- * To build a container run `docker build .`
171
+ * To build a container run `docker build . -t sneakers_sneakers`
165
172
  * To run non-integration tests within a docker container, run `docker run --rm
166
173
  sneakers_sneakers:latest`
167
174
  * To run full integration tests within a docker topology including RabbitMQ,
@@ -176,23 +183,20 @@ environment needed locally on your development box.
176
183
  It generates a more compact image, while the "regular" `Dockerfile` generates
177
184
  a fatter image - yet faster to iterate when developing
178
185
 
179
-
180
186
  # Compatibility
181
187
 
182
- * Sneakers 1.1.x and up (using the new generation Bunny 2.x) - Ruby 2.x.x
183
- * Sneakers 1.x.x and down - Ruby 1.9.x, 2.x.x
188
+ * Sneakers 2.7.x and later (using Bunny 2.9) - Ruby 2.2.x
189
+ * Sneakers 1.1.x and later (using Bunny 2.x) - Ruby 2.x
190
+ * Sneakers 1.x.x and earlier - Ruby 1.9.x, 2.x
184
191
 
185
192
  # Contributing
186
193
 
187
194
  Fork, implement, add tests, pull request, get my everlasting thanks and a respectable place here :).
188
195
 
189
-
190
196
  ### Thanks:
191
197
 
192
198
  To all Sneakers [Contributors](https://github.com/jondot/sneakers/graphs/contributors) - you make this happen, thanks!
193
199
 
194
-
195
-
196
200
  # Copyright
197
201
 
198
- Copyright (c) 2015 [Dotan Nahum](http://gplus.to/dotan) [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details.
202
+ Copyright (c) 2015-2018 [Dotan Nahum](http://gplus.to/dotan) [@jondot](http://twitter.com/jondot). See [LICENSE](LICENSE.txt) for further details.
@@ -1,17 +1,20 @@
1
- version: '2'
1
+ version: '3'
2
+
2
3
  services:
3
4
  sneakers:
4
5
  build: .
5
6
  depends_on:
6
7
  - rabbitmq
7
8
  - redis
9
+
8
10
  rabbitmq:
9
- image: rabbitmq:management
11
+ image: rabbitmq:management-alpine
10
12
  ports:
11
13
  - "5672:5672"
12
14
  - "15672:15672"
15
+
13
16
  redis:
14
- image: redis
17
+ image: redis:alpine
15
18
  ports:
16
19
  - "6379:6379"
17
20
 
@@ -37,7 +37,6 @@ module Sneakers
37
37
  :amqp_heartbeat => 30,
38
38
 
39
39
  # workers
40
- :timeout_job_after => 5,
41
40
  :prefetch => 10,
42
41
  :threads => 10,
43
42
  :share_threads => false,
@@ -1,5 +1,2 @@
1
- require 'timeout'
2
-
3
1
  module Sneakers
4
- class WorkerTimeout < Timeout::Error; end
5
2
  end
@@ -5,7 +5,7 @@ module Sneakers
5
5
  module Handlers
6
6
  #
7
7
  # Maxretry uses dead letter policies on Rabbitmq to requeue and retry
8
- # messages after failure (rejections, errors and timeouts). When the maximum
8
+ # messages after failure (rejections and errors). When the maximum
9
9
  # number of retries is reached it will put the message on an error queue.
10
10
  # This handler will only retry at the queue level. To accomplish that, the
11
11
  # setup is a bit complex.
@@ -101,10 +101,6 @@ module Sneakers
101
101
  handle_retry(hdr, props, msg, err)
102
102
  end
103
103
 
104
- def timeout(hdr, props, msg)
105
- handle_retry(hdr, props, msg, :timeout)
106
- end
107
-
108
104
  def noop(hdr, props, msg)
109
105
 
110
106
  end
@@ -18,10 +18,6 @@ module Sneakers
18
18
  reject(hdr, props, msg)
19
19
  end
20
20
 
21
- def timeout(hdr, props, msg)
22
- reject(hdr, props, msg)
23
- end
24
-
25
21
  def noop(hdr, props, msg)
26
22
 
27
23
  end
@@ -38,7 +38,11 @@ class Sneakers::Queue
38
38
 
39
39
  if exchange_name.length > 0
40
40
  routing_keys.each do |key|
41
- queue.bind(@exchange, :routing_key => key)
41
+ if @opts[:bind_arguments]
42
+ queue.bind(@exchange, routing_key: key, arguments: @opts[:bind_arguments])
43
+ else
44
+ queue.bind(@exchange, routing_key: key)
45
+ end
42
46
  end
43
47
  end
44
48
 
@@ -49,7 +53,7 @@ class Sneakers::Queue
49
53
  handler_klass = worker.opts[:handler] || Sneakers::CONFIG.fetch(:handler)
50
54
  handler = handler_klass.new(@channel, queue, worker.opts)
51
55
 
52
- @consumer = queue.subscribe(:block => false, :manual_ack => @opts[:ack]) do | delivery_info, metadata, msg |
56
+ @consumer = queue.subscribe(block: false, manual_ack: @opts[:ack]) do | delivery_info, metadata, msg |
53
57
  worker.do_work(delivery_info, metadata, msg, handler)
54
58
  end
55
59
  nil
@@ -72,10 +76,10 @@ class Sneakers::Queue
72
76
  end
73
77
 
74
78
  def create_bunny_connection
75
- Bunny.new(@opts[:amqp], :vhost => @opts[:vhost],
76
- :heartbeat => @opts[:heartbeat],
77
- :properties => @opts.fetch(:properties, {}),
78
- :logger => Sneakers::logger)
79
+ Bunny.new(@opts[:amqp], vhost: @opts[:vhost],
80
+ heartbeat: @opts[:heartbeat],
81
+ properties: @opts.fetch(:properties, {}),
82
+ logger: Sneakers::logger)
79
83
  end
80
84
  private :create_bunny_connection
81
85
  end
@@ -1,3 +1,3 @@
1
1
  module Sneakers
2
- VERSION = "2.7.0"
2
+ VERSION = "2.11.0"
3
3
  end
@@ -1,6 +1,5 @@
1
1
  require 'sneakers/queue'
2
2
  require 'sneakers/support/utils'
3
- require 'timeout'
4
3
 
5
4
  module Sneakers
6
5
  module Worker
@@ -18,7 +17,6 @@ module Sneakers
18
17
  opts = Sneakers::CONFIG.merge(opts)
19
18
 
20
19
  @should_ack = opts[:ack]
21
- @timeout_after = opts[:timeout_job_after]
22
20
  @pool = pool || Concurrent::FixedThreadPool.new(opts[:threads] || Sneakers::Configuration::DEFAULTS[:threads])
23
21
  @call_with_params = respond_to?(:work_with_params)
24
22
  @content_type = opts[:content_type]
@@ -57,21 +55,15 @@ module Sneakers
57
55
 
58
56
  begin
59
57
  metrics.increment("work.#{self.class.name}.started")
60
- Timeout.timeout(@timeout_after, WorkerTimeout) do
61
- metrics.timing("work.#{self.class.name}.time") do
62
- deserialized_msg = ContentType.deserialize(msg, @content_type || metadata && metadata[:content_type])
63
- if @call_with_params
64
- res = work_with_params(deserialized_msg, delivery_info, metadata)
65
- else
66
- res = work(deserialized_msg)
67
- end
58
+ metrics.timing("work.#{self.class.name}.time") do
59
+ deserialized_msg = ContentType.deserialize(msg, @content_type || metadata && metadata[:content_type])
60
+ if @call_with_params
61
+ res = work_with_params(deserialized_msg, delivery_info, metadata)
62
+ else
63
+ res = work(deserialized_msg)
68
64
  end
69
65
  end
70
- rescue WorkerTimeout => ex
71
- res = :timeout
72
- worker_error(ex, log_msg: log_msg(msg), class: self.class.name,
73
- message: msg, delivery_info: delivery_info, metadata: metadata)
74
- rescue => ex
66
+ rescue StandardError, ScriptError => ex
75
67
  res = :error
76
68
  error = ex
77
69
  worker_error(ex, log_msg: log_msg(msg), class: self.class.name,
@@ -83,8 +75,6 @@ module Sneakers
83
75
  if res == :ack
84
76
  # note to future-self. never acknowledge multiple (multiple=true) messages under threads.
85
77
  handler.acknowledge(delivery_info, metadata, msg)
86
- elsif res == :timeout
87
- handler.timeout(delivery_info, metadata, msg)
88
78
  elsif res == :error
89
79
  handler.error(delivery_info, metadata, msg, error)
90
80
  elsif res == :reject
File without changes
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'sneakers/version'
@@ -18,22 +17,24 @@ Gem::Specification.new do |gem|
18
17
  gem.executables = gem.files.grep(/^bin/).map { |f| File.basename(f) }
19
18
  gem.test_files = gem.files.grep(/^(test|spec|features)\//)
20
19
  gem.require_paths = ['lib']
20
+
21
21
  gem.add_dependency 'serverengine', '~> 2.0.5'
22
- gem.add_dependency 'bunny', '~> 2.9.2'
22
+ gem.add_dependency 'bunny', '~> 2.12'
23
23
  gem.add_dependency 'concurrent-ruby', '~> 1.0'
24
24
  gem.add_dependency 'thor'
25
+ gem.add_dependency 'rake'
25
26
 
26
27
  # for integration environment (see .travis.yml and integration_spec)
27
28
  gem.add_development_dependency 'rabbitmq_http_api_client'
28
29
  gem.add_development_dependency 'redis'
29
30
 
31
+ gem.add_development_dependency 'rake'
32
+ gem.add_development_dependency 'minitest'
30
33
  gem.add_development_dependency 'rr'
31
34
  gem.add_development_dependency 'unparser', '0.2.2' # keep below 0.2.5 for ruby 2.0 compat.
32
- gem.add_development_dependency 'guard-minitest'
33
35
  gem.add_development_dependency 'metric_fu'
34
36
  gem.add_development_dependency 'simplecov'
35
37
  gem.add_development_dependency 'simplecov-rcov-text'
36
- gem.add_development_dependency 'rake'
37
- gem.add_development_dependency 'minitest'
38
38
  gem.add_development_dependency 'guard'
39
+ gem.add_development_dependency 'guard-minitest'
39
40
  end
@@ -74,6 +74,17 @@ describe Sneakers::Queue do
74
74
  q.subscribe(@mkworker)
75
75
  end
76
76
 
77
+ it "supports setting arguments when binding" do
78
+ mock(@mkchan).queue("downloads", :durable => true) { @mkqueue }
79
+ q = Sneakers::Queue.new("downloads",
80
+ queue_vars.merge(:bind_arguments => { "os" => "linux", "cores" => 8 }))
81
+
82
+ mock(@mkqueue).bind(@mkex, :routing_key => "downloads", :arguments => { "os" => "linux", "cores" => 8 })
83
+ mock(@mkqueue).subscribe(:block => false, :manual_ack => true)
84
+
85
+ q.subscribe(@mkworker)
86
+ end
87
+
77
88
  it "will use whatever handler the worker specifies" do
78
89
  mock(@mkchan).queue("downloads", :durable => true) { @mkqueue }
79
90
  @handler = Object.new
@@ -4,7 +4,7 @@ require 'sneakers'
4
4
  require 'sneakers/runner'
5
5
 
6
6
  describe Sneakers::Runner do
7
- let(:logger) { Logger.new('logtest.log') }
7
+ let(:logger) { Logger.new('log/logtest.log') }
8
8
 
9
9
  describe "with configuration that specifies a logger object" do
10
10
  before do
@@ -27,7 +27,7 @@ describe Sneakers::Runner do
27
27
  end
28
28
 
29
29
  describe Sneakers::RunnerConfig do
30
- let(:logger) { Logger.new("logtest.log") }
30
+ let(:logger) { Logger.new("log/logtest.log") }
31
31
  let(:runner_config) { Sneakers::Runner.new([]).instance_variable_get("@runnerconfig") }
32
32
 
33
33
  describe "with a connection" do
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
  require 'sneakers'
3
- require 'timeout'
4
3
  require 'sneakers/handlers/oneshot'
5
4
  require 'sneakers/handlers/maxretry'
6
5
  require 'json'
@@ -77,13 +76,7 @@ describe 'Handlers' do
77
76
  worker.do_work(@header, nil, :requeue, @handler)
78
77
  end
79
78
 
80
- it 'should work and handle user-land timeouts' do
81
- mock(channel).reject(37, false)
82
-
83
- worker.do_work(@header, nil, :timeout, @handler)
84
- end
85
-
86
- it 'should work and handle user-land error' do
79
+ it 'should work and handle user code error' do
87
80
  mock(channel).reject(37, false)
88
81
 
89
82
  worker.do_work(@header, nil, StandardError.new('boom!'), @handler)
@@ -198,7 +191,6 @@ describe 'Handlers' do
198
191
 
199
192
  # it 'allows overriding the retry exchange name'
200
193
  # it 'allows overriding the error exchange name'
201
- # it 'allows overriding the retry timeout'
202
194
 
203
195
  describe '#do_work' do
204
196
  before do
@@ -289,36 +281,6 @@ describe 'Handlers' do
289
281
 
290
282
  end
291
283
 
292
- describe 'timeouts' do
293
- describe 'more retries ahead' do
294
- it 'should reject the message' do
295
- mock(channel).reject(37, false)
296
-
297
- worker.do_work(@header, @props_with_x_death, :timeout, @handler)
298
- end
299
- end
300
-
301
- describe 'no more retries left' do
302
- let(:max_retries) { 1 }
303
-
304
- it 'sends the rejection to the error queue' do
305
- mock(@header).routing_key { '#' }
306
- mock(channel).acknowledge(37, false)
307
- @error_exchange.extend MockPublish
308
-
309
- worker.do_work(@header, @props_with_x_death, :timeout, @handler)
310
- @error_exchange.called.must_equal(true)
311
- @error_exchange.opts.must_equal({ :routing_key => '#' })
312
- data = JSON.parse(@error_exchange.data)
313
- data['error'].must_equal('timeout')
314
- data['num_attempts'].must_equal(2)
315
- data['payload'].must_equal(Base64.encode64(:timeout.to_s))
316
- data['properties'].must_equal(Base64.encode64(@props_with_x_death.to_json))
317
- Time.parse(data['failed_at']).wont_be_nil
318
- end
319
- end
320
- end
321
-
322
284
  describe 'exceptions' do
323
285
  describe 'more retries ahead' do
324
286
  it 'should reject the message' do
@@ -360,33 +322,6 @@ describe 'Handlers' do
360
322
  it 'should work and handle noops' do
361
323
  worker.do_work(@header, @props, :wait, @handler)
362
324
  end
363
-
364
- # Since we encode in json, we want to make sure if the actual payload is
365
- # json, then it's something you can get back out.
366
- describe 'JSON payloads' do
367
- let(:max_retries) { 1 }
368
-
369
- it 'properly encodes the json payload' do
370
- mock(@header).routing_key { '#' }
371
- mock(channel).acknowledge(37, false)
372
- @error_exchange.extend MockPublish
373
-
374
- payload = {
375
- data: 'hello',
376
- response: :timeout
377
- }
378
- worker.do_work(@header, @props_with_x_death, payload.to_json, @handler)
379
- @error_exchange.called.must_equal(true)
380
- @error_exchange.opts.must_equal({ :routing_key => '#' })
381
- data = JSON.parse(@error_exchange.data)
382
- data['error'].must_equal('timeout')
383
- data['num_attempts'].must_equal(2)
384
- data['payload'].must_equal(Base64.encode64(payload.to_json))
385
- data['properties'].must_equal(Base64.encode64(@props_with_x_death.to_json))
386
- end
387
-
388
- end
389
-
390
325
  end
391
326
  end
392
327
  end
@@ -1,6 +1,5 @@
1
1
  require 'spec_helper'
2
2
  require 'sneakers'
3
- require 'timeout'
4
3
  require 'serverengine'
5
4
 
6
5
  class DummyWorker
@@ -21,7 +20,6 @@ class DummyWorker
21
20
  :ack => false,
22
21
  :threads => 50,
23
22
  :prefetch => 40,
24
- :timeout_job_after => 1,
25
23
  :exchange => 'dummy',
26
24
  :heartbeat => 5
27
25
 
@@ -37,16 +35,6 @@ class DefaultsWorker
37
35
  end
38
36
  end
39
37
 
40
- class TimeoutWorker
41
- include Sneakers::Worker
42
- from_queue 'defaults',
43
- :timeout_job_after => 0.5,
44
- :ack => true
45
-
46
- def work(msg)
47
- end
48
- end
49
-
50
38
  class AcksWorker
51
39
  include Sneakers::Worker
52
40
  from_queue 'defaults',
@@ -110,8 +98,7 @@ end
110
98
  class MetricsWorker
111
99
  include Sneakers::Worker
112
100
  from_queue 'defaults',
113
- :ack => true,
114
- :timeout_job_after => 0.5
101
+ :ack => true
115
102
 
116
103
  def work(msg)
117
104
  metrics.increment "foobar"
@@ -122,8 +109,7 @@ end
122
109
  class WithParamsWorker
123
110
  include Sneakers::Worker
124
111
  from_queue 'defaults',
125
- :ack => true,
126
- :timeout_job_after => 0.5
112
+ :ack => true
127
113
 
128
114
  def work_with_params(msg, delivery_info, metadata)
129
115
  msg
@@ -144,21 +130,6 @@ end
144
130
 
145
131
  TestPool ||= Concurrent::ImmediateExecutor
146
132
 
147
- def with_test_queuefactory(ctx, ack=true, msg=nil, nowork=false)
148
- qf = Object.new
149
- q = Object.new
150
- s = Object.new
151
- hdr = Object.new
152
- mock(qf).build_queue(anything, anything, anything) { q }
153
- mock(q).subscribe(anything){ s }
154
-
155
- mock(s).each(anything) { |h,b| b.call(hdr, msg) unless nowork }
156
- mock(hdr).ack{true} if !nowork && ack
157
- mock(hdr).reject{true} if !nowork && !ack
158
-
159
- mock(ctx).queue_factory { qf } # should return our own
160
- end
161
-
162
133
  describe Sneakers::Worker do
163
134
  before do
164
135
  @queue = Object.new
@@ -168,7 +139,7 @@ describe Sneakers::Worker do
168
139
  stub(@queue).exchange { @exchange }
169
140
 
170
141
  Sneakers.clear!
171
- Sneakers.configure(:daemonize => true, :log => 'sneakers.log')
142
+ Sneakers.configure(daemonize: true, log: 'sneakers.log')
172
143
  Sneakers::Worker.configure_metrics
173
144
  end
174
145
 
@@ -202,7 +173,6 @@ describe Sneakers::Worker do
202
173
  :workers => 4,
203
174
  :log => "sneakers.log",
204
175
  :pid_path => "sneakers.pid",
205
- :timeout_job_after => 5,
206
176
  :prefetch => 10,
207
177
  :threads => 10,
208
178
  :share_threads => false,
@@ -241,7 +211,6 @@ describe Sneakers::Worker do
241
211
  :workers => 4,
242
212
  :log => "sneakers.log",
243
213
  :pid_path => "sneakers.pid",
244
- :timeout_job_after => 1,
245
214
  :prefetch => 40,
246
215
  :threads => 50,
247
216
  :share_threads => false,
@@ -280,7 +249,6 @@ describe Sneakers::Worker do
280
249
  :workers => 4,
281
250
  :log => "sneakers.log",
282
251
  :pid_path => "sneakers.pid",
283
- :timeout_job_after => 5,
284
252
  :prefetch => 10,
285
253
  :threads => 10,
286
254
  :share_threads => false,
@@ -404,26 +372,23 @@ describe Sneakers::Worker do
404
372
  w.do_work(header, nil, "msg", handler)
405
373
  end
406
374
 
407
- it "should log exceptions from workers" do
375
+ it "should catch script exceptions from a bad work" do
376
+ w = AcksWorker.new(@queue, TestPool.new)
377
+ mock(w).work("msg").once{ raise ScriptError }
408
378
  handler = Object.new
409
379
  header = Object.new
410
- w = AcksWorker.new(@queue, TestPool.new)
411
- mock(w).work("msg").once{ raise "foo" }
412
- mock(w.logger).error(/error="foo" error_class=RuntimeError worker_class=AcksWorker backtrace=/)
413
380
  mock(handler).error(header, nil, "msg", anything)
381
+ mock(w.logger).error(/\[Exception error="ScriptError" error_class=ScriptError worker_class=AcksWorker backtrace=.*/)
414
382
  w.do_work(header, nil, "msg", handler)
415
383
  end
416
384
 
417
- it "should timeout if a work takes too long" do
418
- w = TimeoutWorker.new(@queue, TestPool.new)
419
- stub(w).work("msg"){ sleep 10 }
420
-
385
+ it "should log exceptions from workers" do
421
386
  handler = Object.new
422
387
  header = Object.new
423
-
424
- mock(handler).timeout(header, nil, "msg")
425
- mock(w.logger).error(/error="execution expired" error_class=Sneakers::WorkerTimeout worker_class=TimeoutWorker backtrace=/)
426
-
388
+ w = AcksWorker.new(@queue, TestPool.new)
389
+ mock(w).work("msg").once{ raise "foo" }
390
+ mock(w.logger).error(/error="foo" error_class=RuntimeError worker_class=AcksWorker backtrace=/)
391
+ mock(handler).error(header, nil, "msg", anything)
427
392
  w.do_work(header, nil, "msg", handler)
428
393
  end
429
394
 
@@ -456,14 +421,7 @@ describe Sneakers::Worker do
456
421
  @worker.do_work(@delivery_info, nil, :requeue, handler)
457
422
  end
458
423
 
459
- it "should work and handle user-land timeouts" do
460
- handler = Object.new
461
- mock(handler).timeout(@delivery_info, nil, :timeout)
462
-
463
- @worker.do_work(@delivery_info, nil, :timeout, handler)
464
- end
465
-
466
- it "should work and handle user-land error" do
424
+ it "should work and handle user code errors" do
467
425
  handler = Object.new
468
426
  mock(handler).error(@delivery_info, nil, :error, anything)
469
427
 
@@ -557,7 +515,6 @@ describe Sneakers::Worker do
557
515
  # We don't care how these are called, we're focusing on metrics here.
558
516
  stub(@handler).acknowledge
559
517
  stub(@handler).reject
560
- stub(@handler).timeout
561
518
  stub(@handler).error
562
519
  stub(@handler).noop
563
520
 
@@ -594,12 +551,6 @@ describe Sneakers::Worker do
594
551
  @w.do_work(@delivery_info, nil, 'msg', @handler)
595
552
  end
596
553
 
597
- it 'should be able to meter timeouts' do
598
- mock(@w.metrics).increment("work.MetricsWorker.handled.timeout").once
599
- mock(@w).work('msg'){ sleep 10 }
600
- @w.do_work(@delivery_info, nil, 'msg', @handler)
601
- end
602
-
603
554
  it 'defaults to noop when no response is specified' do
604
555
  mock(@w.metrics).increment("foobar").once
605
556
  mock(@w.metrics).increment("work.MetricsWorker.handled.noop").once
@@ -40,7 +40,7 @@ class StubbedWorker
40
40
  end
41
41
 
42
42
  describe Sneakers::WorkerGroup do
43
- let(:logger) { Logger.new('logtest.log') }
43
+ let(:logger) { Logger.new('log/logtest.log') }
44
44
  let(:connection) { Bunny.new(host: 'any-host.local') }
45
45
  let(:runner) { Sneakers::Runner.new([DefaultsWorker]) }
46
46
  let(:runner_config) { runner.instance_variable_get('@runnerconfig') }
@@ -1,6 +1,7 @@
1
1
  require 'bundler/setup'
2
2
  require 'simplecov'
3
3
  require 'resolv'
4
+
4
5
  SimpleCov.start do
5
6
  add_filter "/spec/"
6
7
  end
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.7.0
4
+ version: 2.11.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: 2018-03-22 00:00:00.000000000 Z
11
+ date: 2019-01-19 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.9.2
33
+ version: '2.12'
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.9.2
40
+ version: '2.12'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: concurrent-ruby
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -67,13 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: rabbitmq_http_api_client
70
+ name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :development
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: redis
84
+ name: rabbitmq_http_api_client
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: rr
98
+ name: redis
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,21 +109,21 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: unparser
112
+ name: rake
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
- - - '='
115
+ - - ">="
116
116
  - !ruby/object:Gem::Version
117
- version: 0.2.2
117
+ version: '0'
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.2.2
124
+ version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: guard-minitest
126
+ name: minitest
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,7 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: metric_fu
140
+ name: rr
141
141
  requirement: !ruby/object:Gem::Requirement
142
142
  requirements:
143
143
  - - ">="
@@ -151,7 +151,21 @@ dependencies:
151
151
  - !ruby/object:Gem::Version
152
152
  version: '0'
153
153
  - !ruby/object:Gem::Dependency
154
- name: simplecov
154
+ name: unparser
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 0.2.2
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 0.2.2
167
+ - !ruby/object:Gem::Dependency
168
+ name: metric_fu
155
169
  requirement: !ruby/object:Gem::Requirement
156
170
  requirements:
157
171
  - - ">="
@@ -165,7 +179,7 @@ dependencies:
165
179
  - !ruby/object:Gem::Version
166
180
  version: '0'
167
181
  - !ruby/object:Gem::Dependency
168
- name: simplecov-rcov-text
182
+ name: simplecov
169
183
  requirement: !ruby/object:Gem::Requirement
170
184
  requirements:
171
185
  - - ">="
@@ -179,7 +193,7 @@ dependencies:
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0'
181
195
  - !ruby/object:Gem::Dependency
182
- name: rake
196
+ name: simplecov-rcov-text
183
197
  requirement: !ruby/object:Gem::Requirement
184
198
  requirements:
185
199
  - - ">="
@@ -193,7 +207,7 @@ dependencies:
193
207
  - !ruby/object:Gem::Version
194
208
  version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
- name: minitest
210
+ name: guard
197
211
  requirement: !ruby/object:Gem::Requirement
198
212
  requirements:
199
213
  - - ">="
@@ -207,7 +221,7 @@ dependencies:
207
221
  - !ruby/object:Gem::Version
208
222
  version: '0'
209
223
  - !ruby/object:Gem::Dependency
210
- name: guard
224
+ name: guard-minitest
211
225
  requirement: !ruby/object:Gem::Requirement
212
226
  requirements:
213
227
  - - ">="
@@ -239,7 +253,7 @@ files:
239
253
  - README.md
240
254
  - Rakefile
241
255
  - bin/sneakers
242
- - docker-compose.yaml
256
+ - docker-compose.yml
243
257
  - examples/benchmark_worker.rb
244
258
  - examples/max_retry_handler.rb
245
259
  - examples/metrics_worker.rb
@@ -272,6 +286,7 @@ files:
272
286
  - lib/sneakers/version.rb
273
287
  - lib/sneakers/worker.rb
274
288
  - lib/sneakers/workergroup.rb
289
+ - log/.gitkeep
275
290
  - scripts/local_integration
276
291
  - scripts/local_worker
277
292
  - sneakers.gemspec
@@ -312,7 +327,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
312
327
  version: '0'
313
328
  requirements: []
314
329
  rubyforge_project:
315
- rubygems_version: 2.6.14
330
+ rubygems_version: 2.6.8
316
331
  signing_key:
317
332
  specification_version: 4
318
333
  summary: Fast background processing framework for Ruby and RabbitMQ