delayed_job 3.0.1 → 3.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/MIT-LICENSE CHANGED
@@ -17,4 +17,4 @@ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOa AND
17
17
  NONINFRINGEMENT. IN NO EVENT SaALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
18
  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
19
  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile CHANGED
@@ -37,7 +37,7 @@ Run @bundle install@ to install the backend and delayed_job gems.
37
37
  The Active Record backend requires a jobs table. You can create that table by running the following command:
38
38
 
39
39
  <pre>
40
- $ script/rails generate delayed_job:active_record
40
+ $ rails generate delayed_job:active_record
41
41
  $ rake db:migrate
42
42
  </pre>
43
43
 
@@ -48,7 +48,7 @@ Delayed Job 3.0.0 introduces a new column to the delayed_jobs table.
48
48
  If you're upgrading from Delayed Job 2.x, run the upgrade generator to create a migration to add the column.
49
49
 
50
50
  <pre>
51
- $ script/rails generate delayed_job:upgrade
51
+ $ rails generate delayed_job:upgrade
52
52
  $ rake db:migrate
53
53
  </pre>
54
54
 
@@ -142,7 +142,7 @@ h2. Running Jobs
142
142
 
143
143
  @script/delayed_job@ can be used to manage a background process which will start working off jobs.
144
144
 
145
- To do so, add @gem "daemons"@ to your @Gemfile@ and make sure you've run `script/rails generate delayed_job`.
145
+ To do so, add @gem "daemons"@ to your @Gemfile@ and make sure you've run `rails generate delayed_job`.
146
146
 
147
147
  You can then do the following:
148
148
 
@@ -252,6 +252,8 @@ Delayed::Worker.destroy_failed_jobs = false. The failed jobs will be marked with
252
252
 
253
253
  By default all jobs are scheduled with priority = 0, which is top priority. You can change this by setting Delayed::Worker.default_priority to something else. Lower numbers have higher priority.
254
254
 
255
+ The default behavior is to read 5 jobs from the queue when finding an available job. You can configure this by setting Delayed::Worker.read_ahead.
256
+
255
257
  It is possible to disable delayed jobs for testing purposes. Set Delayed::Worker.delay_jobs = false to execute all jobs realtime.
256
258
 
257
259
  Here is an example of changing job parameters in Rails:
@@ -262,6 +264,7 @@ Delayed::Worker.destroy_failed_jobs = false
262
264
  Delayed::Worker.sleep_delay = 60
263
265
  Delayed::Worker.max_attempts = 3
264
266
  Delayed::Worker.max_run_time = 5.minutes
267
+ Delayed::Worker.read_ahead = 10
265
268
  Delayed::Worker.delay_jobs = !Rails.env.test?
266
269
  </pre>
267
270
 
@@ -11,4 +11,4 @@
11
11
  check process delayed_job
12
12
  with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.pid
13
13
  start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start"
14
- stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop"
14
+ stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop"
@@ -11,13 +11,13 @@ check process delayed_job_0
11
11
  with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.0.pid
12
12
  start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 0"
13
13
  stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 0"
14
-
14
+
15
15
  check process delayed_job_1
16
16
  with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.1.pid
17
17
  start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 1"
18
18
  stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 1"
19
-
19
+
20
20
  check process delayed_job_2
21
21
  with pidfile /var/www/apps/{app_name}/shared/pids/delayed_job.2.pid
22
22
  start program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job start -i 2"
23
- stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 2"
23
+ stop program = "/usr/bin/env RAILS_ENV=production /var/www/apps/{app_name}/current/script/delayed_job stop -i 2"
@@ -41,7 +41,7 @@ module Delayed
41
41
  def reserve(worker, max_run_time = Worker.max_run_time)
42
42
  # We get up to 5 jobs from the db. In case we cannot get exclusive access to a job we try the next.
43
43
  # this leads to a more even distribution of jobs across the worker processes
44
- find_available(worker.name, 5, max_run_time).detect do |job|
44
+ find_available(worker.name, worker.read_ahead, max_run_time).detect do |job|
45
45
  job.lock_exclusively!(max_run_time, worker.name)
46
46
  end
47
47
  end
@@ -61,7 +61,7 @@ module Delayed
61
61
  end
62
62
 
63
63
  def failed?
64
- failed_at
64
+ !!failed_at
65
65
  end
66
66
  alias_method :failed, :failed?
67
67
 
@@ -279,6 +279,27 @@ shared_examples_for 'a delayed_job backend' do
279
279
  end
280
280
  end
281
281
 
282
+ context "worker read-ahead" do
283
+ before do
284
+ @read_ahead = Delayed::Worker.read_ahead
285
+ end
286
+
287
+ after do
288
+ Delayed::Worker.read_ahead = @read_ahead
289
+ end
290
+
291
+ it "should read five jobs" do
292
+ described_class.should_receive(:find_available).with(anything, 5, anything).and_return([])
293
+ described_class.reserve(worker)
294
+ end
295
+
296
+ it "should read a configurable number of jobs" do
297
+ Delayed::Worker.read_ahead = 15
298
+ described_class.should_receive(:find_available).with(anything, Delayed::Worker.read_ahead, anything).and_return([])
299
+ described_class.reserve(worker)
300
+ end
301
+ end
302
+
282
303
  context "clear_locks!" do
283
304
  before do
284
305
  @job = create_job(:locked_by => 'worker1', :locked_at => described_class.db_time_now)
@@ -394,6 +415,14 @@ shared_examples_for 'a delayed_job backend' do
394
415
  job.reload.payload_object.object.text.should == 'goodbye'
395
416
  end
396
417
 
418
+ it "should raise error ArgumentError the record is not persisted" do
419
+ story = Story.new(:text => 'hello')
420
+ lambda {
421
+ story.delay.tell
422
+ }.should raise_error(ArgumentError, "Jobs cannot be created for records before they've been persisted")
423
+
424
+ end
425
+
397
426
  it "should raise deserialization error for destroyed records" do
398
427
  story = Story.create(:text => 'hello')
399
428
  job = story.delay.tell
@@ -430,7 +459,7 @@ shared_examples_for 'a delayed_job backend' do
430
459
  job = described_class.create! :handler => "--- !ruby/object:JobThatDoesNotExist {}"
431
460
  worker.work_off
432
461
  job.reload
433
- job.failed_at.should_not be_nil
462
+ job.should be_failed
434
463
  end
435
464
  end
436
465
  end
@@ -451,7 +480,7 @@ shared_examples_for 'a delayed_job backend' do
451
480
  @job.reload
452
481
  @job.last_error.should =~ /did not work/
453
482
  @job.attempts.should == 1
454
- @job.failed_at.should_not be_nil
483
+ @job.should be_failed
455
484
  end
456
485
 
457
486
  it "should re-schedule jobs after failing" do
@@ -551,14 +580,14 @@ shared_examples_for 'a delayed_job backend' do
551
580
  it_should_behave_like "any failure more than Worker.max_attempts times"
552
581
 
553
582
  it "should be failed if it failed more than Worker.max_attempts times" do
554
- @job.reload.failed_at.should == nil
583
+ @job.reload.should_not be_failed
555
584
  Delayed::Worker.max_attempts.times { worker.reschedule(@job) }
556
- @job.reload.failed_at.should_not == nil
585
+ @job.reload.should be_failed
557
586
  end
558
587
 
559
588
  it "should not be failed if it failed fewer than Worker.max_attempts times" do
560
589
  (Delayed::Worker.max_attempts - 1).times { worker.reschedule(@job) }
561
- @job.reload.failed_at.should == nil
590
+ @job.reload.should_not be_failed
562
591
  end
563
592
  end
564
593
  end
@@ -49,6 +49,9 @@ module Delayed
49
49
  opts.on('--sleep-delay N', "Amount of time to sleep when no jobs are found") do |n|
50
50
  @options[:sleep_delay] = n
51
51
  end
52
+ opts.on('--read-ahead N', "Number of jobs from the queue to consider") do |n|
53
+ @options[:read_ahead] = n
54
+ end
52
55
  opts.on('-p', '--prefix NAME', "String to be prefixed to worker process names") do |prefix|
53
56
  @options[:prefix] = prefix
54
57
  end
@@ -91,7 +94,7 @@ module Delayed
91
94
  Dir.chdir(Rails.root)
92
95
 
93
96
  Delayed::Worker.after_fork
94
- Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
97
+ Delayed::Worker.logger ||= Logger.new(File.join(Rails.root, 'log', 'delayed_job.log'))
95
98
 
96
99
  worker = Delayed::Worker.new(@options)
97
100
  worker.name_prefix = "#{worker_name} "
@@ -1,4 +1,4 @@
1
1
  module Delayed
2
2
  class DeserializationError < StandardError
3
3
  end
4
- end
4
+ end
@@ -1,73 +1,73 @@
1
1
  module Delayed
2
2
  class InvalidCallback < Exception; end
3
-
3
+
4
4
  class Lifecycle
5
5
  EVENTS = {
6
- :enqueue => [:job],
7
- :execute => [:worker],
8
- :loop => [:worker],
9
- :perform => [:worker, :job],
10
- :error => [:worker, :job],
11
- :failure => [:worker, :job],
6
+ :enqueue => [:job],
7
+ :execute => [:worker],
8
+ :loop => [:worker],
9
+ :perform => [:worker, :job],
10
+ :error => [:worker, :job],
11
+ :failure => [:worker, :job],
12
12
  :invoke_job => [:job]
13
13
  }
14
-
14
+
15
15
  def initialize
16
16
  @callbacks = EVENTS.keys.inject({}) { |hash, e| hash[e] = Callback.new; hash }
17
17
  end
18
-
18
+
19
19
  def before(event, &block)
20
20
  add(:before, event, &block)
21
21
  end
22
-
22
+
23
23
  def after(event, &block)
24
24
  add(:after, event, &block)
25
25
  end
26
-
26
+
27
27
  def around(event, &block)
28
28
  add(:around, event, &block)
29
29
  end
30
-
30
+
31
31
  def run_callbacks(event, *args, &block)
32
32
  missing_callback(event) unless @callbacks.has_key?(event)
33
-
33
+
34
34
  unless EVENTS[event].size == args.size
35
35
  raise ArgumentError, "Callback #{event} expects #{EVENTS[event].size} parameter(s): #{EVENTS[event].join(', ')}"
36
36
  end
37
-
37
+
38
38
  @callbacks[event].execute(*args, &block)
39
39
  end
40
-
40
+
41
41
  private
42
-
42
+
43
43
  def add(type, event, &block)
44
44
  missing_callback(event) unless @callbacks.has_key?(event)
45
45
 
46
46
  @callbacks[event].add(type, &block)
47
47
  end
48
-
48
+
49
49
  def missing_callback(event)
50
50
  raise InvalidCallback, "Unknown callback event: #{event}"
51
51
  end
52
52
  end
53
-
53
+
54
54
  class Callback
55
55
  def initialize
56
56
  @before = []
57
57
  @after = []
58
-
58
+
59
59
  # Identity proc. Avoids special cases when there is no existing around chain.
60
60
  @around = lambda { |*args, &block| block.call(*args) }
61
61
  end
62
-
63
- def execute(*args, &block)
62
+
63
+ def execute(*args, &block)
64
64
  @before.each { |c| c.call(*args) }
65
65
  result = @around.call(*args, &block)
66
66
  @after.each { |c| c.call(*args) }
67
67
  result
68
68
  end
69
-
70
- def add(type, &callback)
69
+
70
+ def add(type, &callback)
71
71
  case type
72
72
  when :before
73
73
  @before << callback
@@ -81,4 +81,4 @@ module Delayed
81
81
  end
82
82
  end
83
83
  end
84
- end
84
+ end
@@ -9,6 +9,10 @@ module Delayed
9
9
  def initialize(object, method_name, args)
10
10
  raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)
11
11
 
12
+ if defined?(ActiveRecord) && object.kind_of?(ActiveRecord::Base)
13
+ raise(ArgumentError, 'Jobs cannot be created for records before they\'ve been persisted') if object.attributes[object.class.primary_key].nil?
14
+ end
15
+
12
16
  self.object = object
13
17
  self.args = args
14
18
  self.method_name = method_name.to_sym
@@ -12,4 +12,4 @@ module Delayed
12
12
  self.class.callback_block.call(Delayed::Worker.lifecycle) if self.class.callback_block
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -5,11 +5,11 @@ module Delayed
5
5
  lifecycle.around(:execute) do |worker, &block|
6
6
  begin
7
7
  block.call(worker)
8
- ensure
8
+ ensure
9
9
  Delayed::Job.clear_locks!(worker.name)
10
10
  end
11
- end
11
+ end
12
12
  end
13
13
  end
14
14
  end
15
- end
15
+ end
@@ -89,7 +89,7 @@ module Psych
89
89
  @ss.tokenize o.value
90
90
  end
91
91
  end
92
-
92
+
93
93
  def visit_Psych_Nodes_Mapping_with_class(object)
94
94
  return revive(Psych.load_tags[object.tag], object) if Psych.load_tags[object.tag]
95
95
 
@@ -23,15 +23,15 @@ Capistrano::Configuration.instance.load do
23
23
  def rails_env
24
24
  fetch(:rails_env, false) ? "RAILS_ENV=#{fetch(:rails_env)}" : ''
25
25
  end
26
-
26
+
27
27
  def args
28
28
  fetch(:delayed_job_args, "")
29
29
  end
30
-
30
+
31
31
  def roles
32
32
  fetch(:delayed_job_server_role, :app)
33
33
  end
34
-
34
+
35
35
  desc "Stop the delayed_job process"
36
36
  task :stop, :roles => lambda { roles } do
37
37
  run "cd #{current_path};#{rails_env} script/delayed_job stop"
@@ -47,4 +47,4 @@ Capistrano::Configuration.instance.load do
47
47
  run "cd #{current_path};#{rails_env} script/delayed_job restart #{args}"
48
48
  end
49
49
  end
50
- end
50
+ end
@@ -16,4 +16,4 @@ if defined?(ActiveRecord)
16
16
  ['@attributes']
17
17
  end
18
18
  end
19
- end
19
+ end
@@ -4,16 +4,31 @@ require 'active_support/core_ext/class/attribute_accessors'
4
4
  require 'active_support/core_ext/kernel'
5
5
  require 'active_support/core_ext/enumerable'
6
6
  require 'logger'
7
+ require 'benchmark'
7
8
 
8
9
  module Delayed
9
10
  class Worker
10
- cattr_accessor :min_priority, :max_priority, :max_attempts, :max_run_time, :default_priority, :sleep_delay, :logger, :delay_jobs, :queues
11
- self.sleep_delay = 5
12
- self.max_attempts = 25
13
- self.max_run_time = 4.hours
14
- self.default_priority = 0
15
- self.delay_jobs = true
16
- self.queues = []
11
+ DEFAULT_SLEEP_DELAY = 5
12
+ DEFAULT_MAX_ATTEMPTS = 25
13
+ DEFAULT_MAX_RUN_TIME = 4.hours
14
+ DEFAULT_DEFAULT_PRIORITY = 0
15
+ DEFAULT_DELAY_JOBS = true
16
+ DEFAULT_QUEUES = []
17
+ DEFAULT_READ_AHEAD = 5
18
+
19
+ cattr_accessor :min_priority, :max_priority, :max_attempts, :max_run_time, :default_priority, :sleep_delay, :logger, :delay_jobs, :queues, :read_ahead
20
+
21
+ def self.reset
22
+ self.sleep_delay = DEFAULT_SLEEP_DELAY
23
+ self.max_attempts = DEFAULT_MAX_ATTEMPTS
24
+ self.max_run_time = DEFAULT_MAX_RUN_TIME
25
+ self.default_priority = DEFAULT_DEFAULT_PRIORITY
26
+ self.delay_jobs = DEFAULT_DELAY_JOBS
27
+ self.queues = DEFAULT_QUEUES
28
+ self.read_ahead = DEFAULT_READ_AHEAD
29
+ end
30
+
31
+ reset
17
32
 
18
33
  # Add or remove plugins in this list before the worker is instantiated
19
34
  cattr_accessor :plugins
@@ -81,8 +96,9 @@ module Delayed
81
96
  @quiet = options.has_key?(:quiet) ? options[:quiet] : true
82
97
  self.class.min_priority = options[:min_priority] if options.has_key?(:min_priority)
83
98
  self.class.max_priority = options[:max_priority] if options.has_key?(:max_priority)
84
- self.class.sleep_delay = options[:sleep_delay] if options.has_key?(:sleep_delay)
85
- self.class.queues = options[:queues] if options.has_key?(:queues)
99
+ self.class.sleep_delay = options[:sleep_delay] if options.has_key?(:sleep_delay)
100
+ self.class.read_ahead = options[:read_ahead] if options.has_key?(:read_ahead)
101
+ self.class.queues = options[:queues] if options.has_key?(:queues)
86
102
 
87
103
  self.plugins.each { |klass| klass.new }
88
104
  end
@@ -4,4 +4,4 @@ module Autoloaded
4
4
  def perform
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -3,4 +3,4 @@ module Autoloaded
3
3
  def perform
4
4
  end
5
5
  end
6
- end
6
+ end
@@ -3,4 +3,4 @@ module Autoloaded
3
3
  def perform
4
4
  end
5
5
  end
6
- end
6
+ end
@@ -4,4 +4,4 @@ module Autoloaded
4
4
  def perform
5
5
  end
6
6
  end
7
- end
7
+ end
@@ -15,55 +15,55 @@ module Delayed
15
15
  attr_accessor :locked_by
16
16
  attr_accessor :failed_at
17
17
  attr_accessor :queue
18
-
18
+
19
19
  include Delayed::Backend::Base
20
20
 
21
21
  cattr_accessor :id
22
22
  self.id = 0
23
-
23
+
24
24
  def initialize(hash = {})
25
25
  self.attempts = 0
26
26
  self.priority = 0
27
27
  self.id = (self.class.id += 1)
28
28
  hash.each{|k,v| send(:"#{k}=", v)}
29
29
  end
30
-
30
+
31
31
  @jobs = []
32
32
  def self.all
33
33
  @jobs
34
34
  end
35
-
36
- def self.count
35
+
36
+ def self.count
37
37
  all.size
38
38
  end
39
-
39
+
40
40
  def self.delete_all
41
41
  all.clear
42
42
  end
43
-
43
+
44
44
  def self.create(attrs = {})
45
45
  new(attrs).tap do |o|
46
46
  o.save
47
47
  end
48
48
  end
49
-
49
+
50
50
  def self.create!(*args); create(*args); end
51
-
51
+
52
52
  def self.clear_locks!(worker_name)
53
53
  all.select{|j| j.locked_by == worker_name}.each {|j| j.locked_by = nil; j.locked_at = nil}
54
54
  end
55
55
 
56
56
  # Find a few candidate jobs to run (in case some immediately get locked by others).
57
57
  def self.find_available(worker_name, limit = 5, max_run_time = Worker.max_run_time)
58
- jobs = all.select do |j|
59
- j.run_at <= db_time_now &&
58
+ jobs = all.select do |j|
59
+ j.run_at <= db_time_now &&
60
60
  (j.locked_at.nil? || j.locked_at < db_time_now - max_run_time || j.locked_by == worker_name) &&
61
- j.failed_at.nil?
61
+ !j.failed?
62
62
  end
63
-
63
+
64
64
  jobs = jobs.select{|j| Worker.queues.include?(j.queue)} if Worker.queues.any?
65
65
  jobs = jobs.select{|j| j.priority >= Worker.min_priority} if Worker.min_priority
66
- jobs = jobs.select{|j| j.priority <= Worker.max_priority} if Worker.max_priority
66
+ jobs = jobs.select{|j| j.priority <= Worker.max_priority} if Worker.max_priority
67
67
  jobs.sort_by{|j| [j.priority, j.run_at]}[0..limit-1]
68
68
  end
69
69
 
@@ -83,25 +83,25 @@ module Delayed
83
83
  def self.db_time_now
84
84
  Time.current
85
85
  end
86
-
86
+
87
87
  def update_attributes(attrs = {})
88
88
  attrs.each{|k,v| send(:"#{k}=", v)}
89
89
  save
90
90
  end
91
-
91
+
92
92
  def destroy
93
93
  self.class.all.delete(self)
94
94
  end
95
-
95
+
96
96
  def save
97
97
  self.run_at ||= Time.current
98
-
98
+
99
99
  self.class.all << self unless self.class.all.include?(self)
100
100
  true
101
101
  end
102
-
102
+
103
103
  def save!; save; end
104
-
104
+
105
105
  def reload
106
106
  reset
107
107
  self
@@ -1 +1 @@
1
- foo: *bar
1
+ foo: *bar
@@ -64,4 +64,4 @@ describe Delayed::Lifecycle do
64
64
  lifecycle.before(:execute, &callback)
65
65
  expect { lifecycle.run_callbacks(:execute, 1,2,3) {} }.to raise_error(ArgumentError, /1 parameter/)
66
66
  end
67
- end
67
+ end
@@ -13,7 +13,7 @@ describe Delayed::MessageSending do
13
13
  end
14
14
 
15
15
  it "should create a PerformableMethod" do
16
- story = Story.new
16
+ story = Story.create
17
17
  lambda {
18
18
  job = story.tell!(1)
19
19
  job.payload_object.class.should == Delayed::PerformableMethod
@@ -89,7 +89,7 @@ describe Delayed::MessageSending do
89
89
  job.run_at.should == run_at
90
90
  job.priority.should == 20
91
91
  end
92
-
92
+
93
93
  it "should not delay the job when delay_jobs is false" do
94
94
  Delayed::Worker.delay_jobs = false
95
95
  fairy_tail = FairyTail.new
@@ -99,7 +99,7 @@ describe Delayed::MessageSending do
99
99
  }.should change(fairy_tail, :happy_ending).from(nil).to(true)
100
100
  }.should_not change { Delayed::Job.count }
101
101
  end
102
-
102
+
103
103
  it "should delay the job when delay_jobs is true" do
104
104
  Delayed::Worker.delay_jobs = true
105
105
  fairy_tail = FairyTail.new
@@ -42,31 +42,31 @@ describe Delayed::PerformableMethod do
42
42
  describe "hooks" do
43
43
  %w(enqueue before after success).each do |hook|
44
44
  it "should delegate #{hook} hook to object" do
45
- story = Story.new
45
+ story = Story.create
46
46
  story.should_receive(hook).with(an_instance_of(Delayed::Job))
47
47
  story.delay.tell.invoke_job
48
48
  end
49
49
  end
50
-
50
+
51
51
  %w(before after success).each do |hook|
52
52
  it "should delegate #{hook} hook to object when delay_jobs = false" do
53
53
  Delayed::Worker.delay_jobs = false
54
- story = Story.new
54
+ story = Story.create
55
55
  story.should_receive(hook).with(an_instance_of(Delayed::Job))
56
56
  story.delay.tell
57
57
  end
58
58
  end
59
-
59
+
60
60
  it "should delegate error hook to object" do
61
- story = Story.new
61
+ story = Story.create
62
62
  story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
63
63
  story.should_receive(:tell).and_raise(RuntimeError)
64
64
  lambda { story.delay.tell.invoke_job }.should raise_error
65
65
  end
66
-
66
+
67
67
  it "should delegate error hook to object when delay_jobs = false" do
68
68
  Delayed::Worker.delay_jobs = false
69
- story = Story.new
69
+ story = Story.create
70
70
  story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
71
71
  story.should_receive(:tell).and_raise(RuntimeError)
72
72
  lambda { story.delay.tell }.should raise_error
@@ -77,13 +77,13 @@ describe Delayed::PerformableMethod do
77
77
  method.object.should_receive(:failure)
78
78
  method.failure
79
79
  end
80
-
80
+
81
81
  it "should delegate failure hook to object when delay_jobs = false" do
82
82
  Delayed::Worker.delay_jobs = false
83
83
  method = Delayed::PerformableMethod.new("object", :size, [])
84
84
  method.object.should_receive(:failure)
85
85
  method.failure
86
86
  end
87
-
87
+
88
88
  end
89
89
  end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,11 @@
1
- $:.unshift(File.dirname(__FILE__) + '/../lib')
1
+ unless ENV['CI']
2
+ require 'simplecov'
3
+ SimpleCov.start
4
+ end
2
5
 
3
6
  require 'bundler/setup'
4
7
  require 'logger'
5
8
 
6
- require 'rails'
7
9
  require 'action_mailer'
8
10
  require 'active_support/dependencies'
9
11
  require 'active_record'
@@ -36,10 +38,16 @@ ActiveRecord::Schema.define do
36
38
  end
37
39
 
38
40
  class Story < ActiveRecord::Base
39
- set_primary_key :story_id
41
+ self.primary_key = 'story_id'
40
42
  def tell; text; end
41
43
  def whatever(n, _); tell*n; end
42
44
  default_scope where(:scoped => true)
43
45
 
44
46
  handle_asynchronously :whatever
45
47
  end
48
+
49
+ RSpec.configure do |config|
50
+ config.after(:each) do
51
+ Delayed::Worker.reset
52
+ end
53
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Delayed::Backend::Test::Job do
4
4
  it_should_behave_like 'a delayed_job backend'
5
-
5
+
6
6
  describe "#reload" do
7
7
  it 'should cause the payload object to be reloaded' do
8
8
  job = "foo".delay.length
@@ -10,4 +10,4 @@ describe Delayed::Backend::Test::Job do
10
10
  o.object_id.should_not == job.reload.payload_object.object_id
11
11
  end
12
12
  end
13
- end
13
+ end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job
3
3
  version: !ruby/object:Gem::Version
4
- hash: 5
4
+ hash: 3
5
5
  prerelease:
6
6
  segments:
7
7
  - 3
8
8
  - 0
9
- - 1
10
- version: 3.0.1
9
+ - 2
10
+ version: 3.0.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Matt Griffin
@@ -20,7 +20,7 @@ autorequire:
20
20
  bindir: bin
21
21
  cert_chain: []
22
22
 
23
- date: 2012-01-24 00:00:00 Z
23
+ date: 2012-04-03 00:00:00 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  version_requirements: &id001 !ruby/object:Gem::Requirement
@@ -56,46 +56,46 @@ dependencies:
56
56
  version_requirements: &id003 !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ">="
59
+ - - ~>
60
60
  - !ruby/object:Gem::Version
61
- hash: 3
61
+ hash: 7
62
62
  segments:
63
+ - 3
63
64
  - 0
64
- version: "0"
65
+ version: "3.0"
65
66
  requirement: *id003
66
67
  type: :development
67
68
  prerelease: false
68
- name: sqlite3
69
+ name: actionmailer
69
70
  - !ruby/object:Gem::Dependency
70
71
  version_requirements: &id004 !ruby/object:Gem::Requirement
71
72
  none: false
72
73
  requirements:
73
74
  - - ~>
74
75
  - !ruby/object:Gem::Version
75
- hash: 7
76
+ hash: 3
76
77
  segments:
77
- - 3
78
+ - 2
78
79
  - 0
79
- version: "3.0"
80
+ version: "2.0"
80
81
  requirement: *id004
81
82
  type: :development
82
83
  prerelease: false
83
- name: rails
84
+ name: rspec
84
85
  - !ruby/object:Gem::Dependency
85
86
  version_requirements: &id005 !ruby/object:Gem::Requirement
86
87
  none: false
87
88
  requirements:
88
- - - ~>
89
+ - - ">="
89
90
  - !ruby/object:Gem::Version
90
91
  hash: 3
91
92
  segments:
92
- - 2
93
93
  - 0
94
- version: "2.0"
94
+ version: "0"
95
95
  requirement: *id005
96
96
  type: :development
97
97
  prerelease: false
98
- name: rspec
98
+ name: rake
99
99
  - !ruby/object:Gem::Dependency
100
100
  version_requirements: &id006 !ruby/object:Gem::Requirement
101
101
  none: false
@@ -109,7 +109,7 @@ dependencies:
109
109
  requirement: *id006
110
110
  type: :development
111
111
  prerelease: false
112
- name: rake
112
+ name: simplecov
113
113
  description: |-
114
114
  Delayed_job (or DJ) encapsulates the common pattern of asynchronously executing longer tasks in the background. It is a direct extraction from Shopify where the job table is responsible for a multitude of core tasks.
115
115