backburner 0.4.4 → 0.4.5

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: 5cefef513a8a0bdd3a88721c01eb503c01f4aa3c
4
- data.tar.gz: b9b0506df21468b7496c5a6b7dec90492c0dc899
3
+ metadata.gz: c49c95fffe9a81e2e0f775b07b3659a8557d465a
4
+ data.tar.gz: 69446fcc23d3a4a31c4ce9b569ee3fe61f0309be
5
5
  SHA512:
6
- metadata.gz: 0da929c2d10311de013e5b1943754fdeb5dc75e598cb2e52097510827ebf23df93a8cb788be599fbfc54fbf83f3b15637a0c91825cbeb49c3da995a7f734363e
7
- data.tar.gz: 16783da0512636828941b8a141539c67f4a3dc528f2d0a66e065b4c5c2c3ea710a7c4d658829753362e40f4d3981d6fbb329d4df5c0573d8e006721c5f4692e7
6
+ metadata.gz: d5968d8bd1d3df5d72cd697fa66509f573bceca12781b26f84d9e8ce66f3265affdd65e98231d5780674a959c0dc9691cdb77af476b07c4b7c637677155f371c
7
+ data.tar.gz: b48cdf8db9eefa524d6e653af2876551f0c44d5f8e7e9453f68ce312132859be526224ab2ec1e9d43374265983ffbb8fea836434a425e5a015547b79fd598e1d
@@ -1,5 +1,9 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## Version 0.4.5 (December 16 2013)
4
+
5
+ * FIX #47 Create a backburner connection per thread (Thanks @thcrock)
6
+
3
7
  ## Version 0.4.4 (October 27 2013)
4
8
 
5
9
  * NEW #51 Added ability to set per-queue default ttr's (Thanks @ryanjohns)
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`
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Backburner
2
- VERSION = "0.4.4"
2
+ VERSION = "0.4.5"
3
3
  end
@@ -136,8 +136,9 @@ module Backburner
136
136
  # @example
137
137
  # @worker.work_one_job
138
138
  #
139
- def work_one_job
140
- job = Backburner::Job.new(self.connection.tubes.reserve)
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
- run_while_can
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.tubes.watch!(name)
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
@@ -53,4 +53,4 @@ class TestAsyncJobForking
53
53
  :worker_test_count_set => x * y
54
54
  }], :queue => 'response'
55
55
  end
56
- end
56
+ 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
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-10-27 00:00:00.000000000 Z
11
+ date: 2013-12-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: beaneater