backburner 0.4.5 → 0.4.6

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: 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