sneakers 2.7.0 → 2.11.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: '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