backburner 0.4.5 → 0.4.6

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: c49c95fffe9a81e2e0f775b07b3659a8557d465a
4
- data.tar.gz: 69446fcc23d3a4a31c4ce9b569ee3fe61f0309be
3
+ metadata.gz: b2b489b60308b955b398ce8a9936c0bfca96588e
4
+ data.tar.gz: 6a22f67c5502cd730139c4a857d4417552419c57
5
5
  SHA512:
6
- metadata.gz: d5968d8bd1d3df5d72cd697fa66509f573bceca12781b26f84d9e8ce66f3265affdd65e98231d5780674a959c0dc9691cdb77af476b07c4b7c637677155f371c
7
- data.tar.gz: b48cdf8db9eefa524d6e653af2876551f0c44d5f8e7e9453f68ce312132859be526224ab2ec1e9d43374265983ffbb8fea836434a425e5a015547b79fd598e1d
6
+ metadata.gz: c751606af667cdeadbfd9d270d5aae80ccc42a9f9f968607f4a02d783207b3db4171ab9cc207e44b38a435024a68b6e6bfcb319973788940f819f6d05b49843a
7
+ data.tar.gz: 5bacb2a1f9c613addac6a7ad3e4c45d9358fdd523092faf50f696fbbb3aede4d0676bddd875caa4fca84d36995bf9bfbd3aafe43fc33fda6e9458539dd6d3421
@@ -1,5 +1,13 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## Version 0.4.6 (October 26 2014)
4
+
5
+ * NEW Add job to on_error handler if the handler has a 4th argument (@Nitrodist)
6
+ * NEW Use a timeout when looking for a job to reserve (@EasyPost)
7
+ * NEW Support configuring settings on threads on fork class (@silentshade)
8
+ * FIX queue override by existing queues (@silentshade)
9
+ * FIX Use thread to log exit message (@silentshade)
10
+
3
11
  ## Version 0.4.5 (December 16 2013)
4
12
 
5
13
  * FIX #47 Create a backburner connection per thread (Thanks @thcrock)
data/README.md CHANGED
@@ -99,6 +99,7 @@ Backburner.configure do |config|
99
99
  config.logger = Logger.new(STDOUT)
100
100
  config.primary_queue = "backburner-jobs"
101
101
  config.priority_labels = { :custom => 50, :useless => 1000 }
102
+ config.reserve_timeout = nil
102
103
  end
103
104
  ```
104
105
 
@@ -115,6 +116,7 @@ The key options available are:
115
116
  | `logger` | Logger recorded to when backburner wants to report info or errors. |
116
117
  | `primary_queue` | Primary queue used for a job when an alternate queue is not given. |
117
118
  | `priority_labels` | Hash of named priority definitions for your app. |
119
+ | `reserve_timeout` | Duration to wait for work from a single server, or nil for forever. |
118
120
 
119
121
  ## Breaking Changes
120
122
 
@@ -482,6 +484,8 @@ jobs processed by your beanstalk workers. An excellent addition to your Backburn
482
484
  * Kristen Tucker - Coming up with the gem name
483
485
  * [Tim Lee](https://github.com/timothy1ee), [Josh Hull](https://github.com/joshbuddy), [Nico Taing](https://github.com/Nico-Taing) - Helping me work through the idea
484
486
  * [Miso](http://gomiso.com) - Open-source friendly place to work
487
+ * [Evgeniy Denisov](https://github.com/silentshade) - Multiple fixes and cleanups
488
+ * [Andy Bakun](https://github.com/thwarted) - Fixes to how multiple beanstalkd instances are processed
485
489
  * [Renan T. Fernandes](https://github.com/ShadowBelmolve) - Added threads_on_fork worker
486
490
  * [Daniel Farrell](https://github.com/danielfarrell) - Added forking worker
487
491
 
@@ -17,7 +17,6 @@ module Backburner
17
17
  runner.execute do |opts|
18
18
  queues = (opts[:queues] ? opts[:queues].split(',') : nil) rescue nil
19
19
  load_enviroment(opts[:require])
20
- p queues
21
20
  Backburner.work(queues)
22
21
  end
23
22
  end
@@ -14,6 +14,7 @@ module Backburner
14
14
  attr_accessor :default_worker # default worker class
15
15
  attr_accessor :primary_queue # the general queue
16
16
  attr_accessor :priority_labels # priority labels
17
+ attr_accessor :reserve_timeout # duration to wait to reserve on a single server
17
18
 
18
19
  def initialize
19
20
  @beanstalk_url = "beanstalk://localhost"
@@ -28,6 +29,7 @@ module Backburner
28
29
  @default_worker = Backburner::Workers::Simple
29
30
  @primary_queue = "backburner-jobs"
30
31
  @priority_labels = PRIORITY_LABELS
32
+ @reserve_timeout = nil
31
33
  end
32
34
  end # Configuration
33
- end # Backburner
35
+ end # Backburner
@@ -80,6 +80,7 @@ module Backburner
80
80
  # Expands a tube to include the prefix
81
81
  #
82
82
  # @example
83
+ # expand_tube_name("foo_with_settings:3:100:6") # => <prefix>.foo_with_settings
83
84
  # expand_tube_name("foo") # => <prefix>.foo
84
85
  # expand_tube_name(FooJob) # => <prefix>.foo-job
85
86
  #
@@ -94,7 +95,7 @@ module Backburner
94
95
  else # turn into a string
95
96
  tube.to_s
96
97
  end
97
- [prefix.gsub(/\.$/, ''), dasherize(queue_name).gsub(/^#{prefix}/, '')].join(".").gsub(/\.+/, '.')
98
+ [prefix.gsub(/\.$/, ''), dasherize(queue_name).gsub(/^#{prefix}/, '')].join(".").gsub(/\.+/, '.').split(':').first
98
99
  end
99
100
 
100
101
  # Resolves job priority based on the value given. Can be integer, a class or nothing
@@ -47,6 +47,48 @@ module Backburner
47
47
  @queue_respond_timeout
48
48
  end
49
49
  end
50
+
51
+ # Returns or assigns queue parallel active jobs limit (only ThreadsOnFork Worker)
52
+ #
53
+ # @example
54
+ # queue_jobs_limit 5
55
+ # @klass.queue_jobs_limit # => 5
56
+ #
57
+ def queue_jobs_limit(limit=nil)
58
+ if limit
59
+ @queue_jobs_limit = limit
60
+ else #accessor
61
+ @queue_jobs_limit
62
+ end
63
+ end
64
+
65
+ # Returns or assigns queue jobs garbage limit (only ThreadsOnFork Worker)
66
+ #
67
+ # @example
68
+ # queue_garbage_limit 1000
69
+ # @klass.queue_garbage_limit # => 1000
70
+ #
71
+ def queue_garbage_limit(limit=nil)
72
+ if limit
73
+ @queue_garbage_limit = limit
74
+ else #accessor
75
+ @queue_garbage_limit
76
+ end
77
+ end
78
+
79
+ # Returns or assigns queue retry limit (only ThreadsOnFork Worker)
80
+ #
81
+ # @example
82
+ # queue_retry_limit 6
83
+ # @klass.queue_retry_limit # => 6
84
+ #
85
+ def queue_retry_limit(limit=nil)
86
+ if limit
87
+ @queue_retry_limit = limit
88
+ else #accessor
89
+ @queue_retry_limit
90
+ end
91
+ end
50
92
  end # ClassMethods
51
93
  end # Queue
52
- end # Backburner
94
+ end # Backburner
@@ -1,3 +1,3 @@
1
1
  module Backburner
2
- VERSION = "0.4.5"
2
+ VERSION = "0.4.6"
3
3
  end
@@ -58,22 +58,6 @@ module Backburner
58
58
  @connection ||= Connection.new(Backburner.configuration.beanstalk_url)
59
59
  end
60
60
 
61
- # Retries the given command specified in the block several times if there is a connection error
62
- # Used to execute beanstalkd commands in a retryable way
63
- #
64
- # @example
65
- # retryable_command { ... }
66
- # @raise [Beaneater::NotConnected] If beanstalk fails to connect multiple times.
67
- #
68
- def self.retryable_command(max_tries=8, &block)
69
- begin
70
- yield
71
- rescue Beaneater::NotConnected => e
72
- retry_connection!(max_tries)
73
- yield
74
- end
75
- end
76
-
77
61
  # List of tube names to be watched and processed
78
62
  attr_accessor :tube_names
79
63
 
@@ -112,7 +96,9 @@ module Backburner
112
96
 
113
97
  # Triggers this worker to shutdown
114
98
  def shutdown
115
- log_info 'Worker exiting...'
99
+ Thread.new do
100
+ log_info 'Worker exiting...'
101
+ end
116
102
  Kernel.exit
117
103
  end
118
104
 
@@ -138,7 +124,11 @@ module Backburner
138
124
  #
139
125
  def work_one_job(conn = nil)
140
126
  conn ||= self.connection
141
- job = Backburner::Job.new(conn.tubes.reserve)
127
+ begin
128
+ job = Backburner::Job.new(conn.tubes.reserve(Backburner.configuration.reserve_timeout))
129
+ rescue Beaneater::TimedOutError => e
130
+ return
131
+ end
142
132
  self.log_job_begin(job.name, job.args)
143
133
  job.process
144
134
  self.log_job_end(job.name)
@@ -156,7 +146,7 @@ module Backburner
156
146
  job.bury
157
147
  self.log_job_end(job.name, "#{retry_status}, burying") if job_started_at
158
148
  end
159
- handle_error(e, job.name, job.args)
149
+ handle_error(e, job.name, job.args, job)
160
150
  end
161
151
 
162
152
  # Retries the given command specified in the block several times if there is a connection error
@@ -201,7 +191,7 @@ module Backburner
201
191
  def all_existing_queues
202
192
  known_queues = Backburner::Worker.known_queue_classes.map(&:queue)
203
193
  existing_tubes = self.connection.tubes.all.map(&:name).select { |tube| tube =~ /^#{queue_config.tube_namespace}/ }
204
- known_queues + existing_tubes + [queue_config.primary_queue]
194
+ existing_tubes + known_queues + [queue_config.primary_queue]
205
195
  end
206
196
 
207
197
  # Returns a reference to the beanstalk connection
@@ -211,12 +201,14 @@ module Backburner
211
201
 
212
202
  # Handles an error according to custom definition
213
203
  # Used when processing a job that errors out
214
- def handle_error(e, name, args)
204
+ def handle_error(e, name, args, job)
215
205
  if error_handler = Backburner.configuration.on_error
216
206
  if error_handler.arity == 1
217
207
  error_handler.call(e)
218
- else
208
+ elsif error_handler.arity == 3
219
209
  error_handler.call(e, name, args)
210
+ else
211
+ error_handler.call(e, name, args, job)
220
212
  end
221
213
  end
222
214
  end
@@ -238,4 +230,4 @@ module Backburner
238
230
  trap('INT') { shutdown }
239
231
  end
240
232
  end # Worker
241
- end # Backburner
233
+ end # Backburner
@@ -70,6 +70,7 @@ module Backburner
70
70
  def initialize(*args)
71
71
  @tubes_data = {}
72
72
  super
73
+ self.process_tube_options
73
74
  end
74
75
 
75
76
  # Process the special tube_names of ThreadsOnFork worker
@@ -101,11 +102,29 @@ module Backburner
101
102
  end
102
103
  end
103
104
 
105
+ # Process the tube settings
106
+ # This overrides @tubes_data set by process_tube_names method. So a tube has name 'super_job:5:20:10'
107
+ # and the tube class has setting queue_jobs_limit 10, the result limit will be 10
108
+ # If the tube is known by existing beanstalkd queue, but not by class - skip it
109
+ #
110
+ def process_tube_options
111
+ Backburner::Worker.known_queue_classes.each do |queue|
112
+ next if @tubes_data[expand_tube_name(queue)].nil?
113
+ queue_settings = {
114
+ :threads => queue.queue_jobs_limit,
115
+ :garbage => queue.queue_garbage_limit,
116
+ :retries => queue.queue_retry_limit
117
+ }
118
+ @tubes_data[expand_tube_name(queue)].merge!(queue_settings){|k, v1, v2| v2.nil? ? v1 : v2 }
119
+ end
120
+ end
121
+
104
122
  def prepare
105
123
  self.tube_names ||= Backburner.default_queues.any? ? Backburner.default_queues : all_existing_queues
106
124
  self.tube_names = Array(self.tube_names)
107
125
  tube_names.map! { |name| expand_tube_name(name) }
108
- log_info "Working #{tube_names.size} queues: [ #{tube_names.join(', ')} ]"
126
+ tube_display_names = tube_names.map{|name| "#{name}:#{@tubes_data[name].values}"}
127
+ log_info "Working #{tube_names.size} queues: [ #{tube_display_names.join(', ')} ]"
109
128
  end
110
129
 
111
130
  # For each tube we will call fork_and_watch to create the fork
@@ -0,0 +1,14 @@
1
+ class TestJobSettings
2
+ include Backburner::Queue
3
+ queue "job-settings:5:10:6"
4
+ def self.perform; end
5
+ end
6
+
7
+ class TestJobSettingsOverride
8
+ include Backburner::Queue
9
+ queue "job-settings-override:5:10:12"
10
+ queue_jobs_limit 10
11
+ queue_garbage_limit 1000
12
+ queue_retry_limit 2
13
+ def self.perform; end
14
+ end
@@ -1,5 +1,6 @@
1
1
  require File.expand_path('../../test_helper', __FILE__)
2
2
  require File.expand_path('../../fixtures/test_fork_jobs', __FILE__)
3
+ require File.expand_path('../../fixtures/test_queue_settings', __FILE__)
3
4
 
4
5
  describe "Backburner::Workers::ThreadsOnFork module" do
5
6
 
@@ -16,7 +17,8 @@ describe "Backburner::Workers::ThreadsOnFork module" do
16
17
  after do
17
18
  Backburner.configure { |config| config.max_job_retries = 0; config.retry_delay = 5; config.logger = nil }
18
19
  unless @ignore_forks
19
- if @worker_class.instance_variable_get("@child_pids").length > 0
20
+ cpids = @worker_class.instance_variable_get("@child_pids")
21
+ if cpids && cpids.length > 0
20
22
  raise "Why is there forks alive?"
21
23
  end
22
24
  end
@@ -49,6 +51,18 @@ describe "Backburner::Workers::ThreadsOnFork module" do
49
51
  end
50
52
  end
51
53
 
54
+ describe "for process_tube_settings" do
55
+ it "should set the settings specified by queue name in class" do
56
+ worker = @worker_class.new
57
+ assert_equal(worker.instance_variable_get("@tubes_data")['demo.test.job-settings'], { :threads => 5, :garbage => 10, :retries => 6 })
58
+ end
59
+
60
+ it 'should override the tube settings if they are specified directly at class level' do
61
+ worker = @worker_class.new
62
+ assert_equal(worker.instance_variable_get("@tubes_data")['demo.test.job-settings-override'], { :threads => 10, :garbage => 1000, :retries => 2 })
63
+ end
64
+ end
65
+
52
66
  describe "for prepare method" do
53
67
  before do
54
68
  Backburner.configure { |config| config.logger = false }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: backburner
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan Esquenazi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-07 00:00:00.000000000 Z
11
+ date: 2014-10-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: beaneater
@@ -132,6 +132,7 @@ files:
132
132
  - test/fixtures/test_fork_jobs.rb
133
133
  - test/fixtures/test_forking_jobs.rb
134
134
  - test/fixtures/test_jobs.rb
135
+ - test/fixtures/test_queue_settings.rb
135
136
  - test/helpers/templogger.rb
136
137
  - test/helpers_test.rb
137
138
  - test/hooks_test.rb
@@ -176,6 +177,7 @@ test_files:
176
177
  - test/fixtures/test_fork_jobs.rb
177
178
  - test/fixtures/test_forking_jobs.rb
178
179
  - test/fixtures/test_jobs.rb
180
+ - test/fixtures/test_queue_settings.rb
179
181
  - test/helpers/templogger.rb
180
182
  - test/helpers_test.rb
181
183
  - test/hooks_test.rb