backburner 0.4.4 → 0.4.5
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 +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +16 -0
- data/lib/backburner/job.rb +3 -3
- data/lib/backburner/version.rb +1 -1
- data/lib/backburner/worker.rb +3 -2
- data/lib/backburner/workers/threads_on_fork.rb +15 -7
- data/test/fixtures/test_forking_jobs.rb +1 -1
- data/test/workers/threads_on_fork_worker_test.rb +47 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c49c95fffe9a81e2e0f775b07b3659a8557d465a
|
4
|
+
data.tar.gz: 69446fcc23d3a4a31c4ce9b569ee3fe61f0309be
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d5968d8bd1d3df5d72cd697fa66509f573bceca12781b26f84d9e8ce66f3265affdd65e98231d5780674a959c0dc9691cdb77af476b07c4b7c637677155f371c
|
7
|
+
data.tar.gz: b48cdf8db9eefa524d6e653af2876551f0c44d5f8e7e9453f68ce312132859be526224ab2ec1e9d43374265983ffbb8fea836434a425e5a015547b79fd598e1d
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -251,6 +251,22 @@ bundle exec backburner -q newsletter-sender,push-notifier -d -P /var/run/backbur
|
|
251
251
|
This will daemonize the worker and store the pid and logs automatically. For Rails and Padrino, the environment should
|
252
252
|
load automatically. For other cases, use the `-r` flag to specify a file to require.
|
253
253
|
|
254
|
+
### Delaying Jobs
|
255
|
+
|
256
|
+
In Backburner, jobs can be delayed by specifying the `delay` option whenever you enqueue a job. If you want to schedule a job for an hour from now, simply add that option while enqueuing the standard job:
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
Backburner::Worker.enqueue(NewsletterJob, ['foo@admin.com', 'lorem ipsum...'], :delay => 1.hour)
|
260
|
+
```
|
261
|
+
|
262
|
+
or while you schedule an async method call:
|
263
|
+
|
264
|
+
```ruby
|
265
|
+
User.async(:delay => 1.hour).reset_password(@user.id)
|
266
|
+
```
|
267
|
+
|
268
|
+
Backburner will take care of the rest!
|
269
|
+
|
254
270
|
### Persistence
|
255
271
|
|
256
272
|
Jobs are persisted to queues as JSON objects. Let's take our `User`
|
data/lib/backburner/job.rb
CHANGED
@@ -77,10 +77,10 @@ module Backburner
|
|
77
77
|
def timeout_job_after(secs, &block)
|
78
78
|
begin
|
79
79
|
Timeout::timeout(secs) { yield }
|
80
|
-
rescue Timeout::Error
|
81
|
-
raise JobTimeout, "#{name} hit #{secs}s timeout"
|
80
|
+
rescue Timeout::Error => e
|
81
|
+
raise JobTimeout, "#{name} hit #{secs}s timeout.\nbacktrace: #{e.backtrace}"
|
82
82
|
end
|
83
83
|
end
|
84
84
|
|
85
85
|
end # Job
|
86
|
-
end # Backburner
|
86
|
+
end # Backburner
|
data/lib/backburner/version.rb
CHANGED
data/lib/backburner/worker.rb
CHANGED
@@ -136,8 +136,9 @@ module Backburner
|
|
136
136
|
# @example
|
137
137
|
# @worker.work_one_job
|
138
138
|
#
|
139
|
-
def work_one_job
|
140
|
-
|
139
|
+
def work_one_job(conn = nil)
|
140
|
+
conn ||= self.connection
|
141
|
+
job = Backburner::Job.new(conn.tubes.reserve)
|
141
142
|
self.log_job_begin(job.name, job.args)
|
142
143
|
job.process
|
143
144
|
self.log_job_end(job.name)
|
@@ -165,12 +165,17 @@ module Backburner
|
|
165
165
|
@runs = 0
|
166
166
|
|
167
167
|
if @threads_number == 1
|
168
|
-
run_while_can
|
168
|
+
run_while_can(name)
|
169
169
|
else
|
170
170
|
threads_count = Thread.list.count
|
171
171
|
@threads_number.times do
|
172
172
|
create_thread do
|
173
|
-
|
173
|
+
conn = Connection.new(Backburner.configuration.beanstalk_url)
|
174
|
+
begin
|
175
|
+
run_while_can(name, conn)
|
176
|
+
ensure
|
177
|
+
conn.close
|
178
|
+
end
|
174
179
|
end
|
175
180
|
end
|
176
181
|
sleep 0.1 while Thread.list.count > threads_count
|
@@ -180,16 +185,19 @@ module Backburner
|
|
180
185
|
end
|
181
186
|
|
182
187
|
# Run work_one_job while we can
|
183
|
-
def run_while_can
|
188
|
+
def run_while_can(name, conn = nil)
|
189
|
+
conn ||= connection
|
190
|
+
watch_tube(name, conn)
|
184
191
|
while @garbage_after.nil? or @garbage_after > @runs
|
185
192
|
@runs += 1
|
186
|
-
work_one_job
|
193
|
+
work_one_job(conn)
|
187
194
|
end
|
188
195
|
end
|
189
196
|
|
190
197
|
# Shortcut for watching a tube on beanstalk connection
|
191
|
-
def watch_tube(name)
|
192
|
-
connection
|
198
|
+
def watch_tube(name, conn = nil)
|
199
|
+
conn ||= connection
|
200
|
+
conn.tubes.watch!(name)
|
193
201
|
end
|
194
202
|
|
195
203
|
# Exit with Kernel.exit! to avoid at_exit callbacks that should belongs to
|
@@ -236,4 +244,4 @@ at_exit do
|
|
236
244
|
Backburner::Workers::ThreadsOnFork.shutdown = true
|
237
245
|
end
|
238
246
|
Backburner::Workers::ThreadsOnFork.finish_forks
|
239
|
-
end
|
247
|
+
end
|
@@ -192,6 +192,33 @@ describe "Backburner::Workers::ThreadsOnFork module" do
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
195
|
+
it "should create a connection for each thread" do
|
196
|
+
name = 'demo.test.foo'
|
197
|
+
num_threads = 3
|
198
|
+
|
199
|
+
worker = @worker_class.new(%(foo))
|
200
|
+
@worker_class.expects(:threads_number).returns(num_threads)
|
201
|
+
invocations = Array(1..num_threads).map { |i|
|
202
|
+
conn = OpenStruct.new(:num => i)
|
203
|
+
conn.expects(:close)
|
204
|
+
conn
|
205
|
+
}
|
206
|
+
Backburner::Connection.expects(:new).times(num_threads).returns(*invocations)
|
207
|
+
|
208
|
+
# ensure each invocation of run_while_can is with a different connection
|
209
|
+
num_conns = states('num_conns').starts_as(0)
|
210
|
+
invocations.each do |conn|
|
211
|
+
worker.expects(:run_while_can).with(name, conn).when(num_conns.is(conn.num-1)).then(num_conns.is(conn.num))
|
212
|
+
end
|
213
|
+
|
214
|
+
def worker.create_thread(*args, &block); block.call(*args) end
|
215
|
+
silenced do
|
216
|
+
worker.prepare
|
217
|
+
worker.fork_inner(name)
|
218
|
+
end
|
219
|
+
assert_equal(num_threads, num_conns.current_state)
|
220
|
+
end
|
221
|
+
|
195
222
|
it "should set @garbage_after, @threads_number and set retries if needed" do
|
196
223
|
worker = @worker_class.new(%W(foo1 foo2:10 foo3:20:30 foo4:40:50:60))
|
197
224
|
default_threads = 1
|
@@ -327,7 +354,7 @@ describe "Backburner::Workers::ThreadsOnFork module" do
|
|
327
354
|
$worker_success = false
|
328
355
|
$worker_raise = false
|
329
356
|
clear_jobs!('response')
|
330
|
-
clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5')
|
357
|
+
clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5', 'foo.bar.6')
|
331
358
|
@worker_class.threads_number = 1
|
332
359
|
@worker_class.garbage_after = 10
|
333
360
|
silenced do
|
@@ -340,7 +367,8 @@ describe "Backburner::Workers::ThreadsOnFork module" do
|
|
340
367
|
after do
|
341
368
|
@templogger.close
|
342
369
|
clear_jobs!('response')
|
343
|
-
clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5')
|
370
|
+
clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5', 'foo.bar.6')
|
371
|
+
@worker_class.threads_number = 1
|
344
372
|
@worker_class.shutdown = true
|
345
373
|
silenced do
|
346
374
|
@worker_class.stop_forks
|
@@ -409,8 +437,24 @@ describe "Backburner::Workers::ThreadsOnFork module" do
|
|
409
437
|
assert_equal true, $worker_success
|
410
438
|
end # retrying, succeeds
|
411
439
|
|
440
|
+
it "should support a multithreaded worker without deadlocks" do
|
441
|
+
num_threads = 5
|
442
|
+
num_jobs = 8
|
443
|
+
num_jobs.times do
|
444
|
+
@worker_class.enqueue TestJobFork, [6,2], :queue => 'foo.bar.6'
|
445
|
+
end
|
446
|
+
@worker_class.threads_number = num_threads
|
447
|
+
@worker = @worker_class.new('foo.bar.6')
|
448
|
+
@worker.start(false)
|
449
|
+
silenced(2) do
|
450
|
+
@templogger.wait_for_match(/Completed TestJobFork/m)
|
451
|
+
num_jobs.times { @response_worker.work_one_job }
|
452
|
+
end
|
453
|
+
assert_equal num_jobs, $worker_test_count
|
454
|
+
end # multithreaded
|
455
|
+
|
412
456
|
end # practical tests
|
413
457
|
|
414
458
|
end # forking and threading
|
415
459
|
|
416
|
-
end # Backburner::Workers::ThreadsOnFork module
|
460
|
+
end # Backburner::Workers::ThreadsOnFork module
|
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.
|
4
|
+
version: 0.4.5
|
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-
|
11
|
+
date: 2013-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: beaneater
|