delayed_job 3.0.3 → 3.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -9,8 +9,8 @@ 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?
12
+ if object.respond_to?(:new_record?) && object.new_record?
13
+ raise(ArgumentError, 'Jobs cannot be created for records before they\'ve been persisted')
14
14
  end
15
15
 
16
16
  self.object = object
@@ -99,11 +99,7 @@ module Psych
99
99
  payload = Hash[*object.children.map { |c| accept c }]
100
100
  id = payload["attributes"][klass.primary_key]
101
101
  begin
102
- if ActiveRecord::VERSION::MAJOR == 3
103
- klass.unscoped.find(id)
104
- else # Rails 2
105
- klass.with_exclusive_scope { klass.find(id) }
106
- end
102
+ klass.unscoped.find(id)
107
103
  rescue ActiveRecord::RecordNotFound
108
104
  raise Delayed::DeserializationError
109
105
  end
@@ -31,20 +31,24 @@ Capistrano::Configuration.instance.load do
31
31
  def roles
32
32
  fetch(:delayed_job_server_role, :app)
33
33
  end
34
+
35
+ def delayed_job_command
36
+ fetch(:delayed_job_command, "script/delayed_job")
37
+ end
34
38
 
35
39
  desc "Stop the delayed_job process"
36
40
  task :stop, :roles => lambda { roles } do
37
- run "cd #{current_path};#{rails_env} script/delayed_job stop"
41
+ run "cd #{current_path};#{rails_env} #{delayed_job_command} stop"
38
42
  end
39
43
 
40
44
  desc "Start the delayed_job process"
41
45
  task :start, :roles => lambda { roles } do
42
- run "cd #{current_path};#{rails_env} script/delayed_job start #{args}"
46
+ run "cd #{current_path};#{rails_env} #{delayed_job_command} start #{args}"
43
47
  end
44
48
 
45
49
  desc "Restart the delayed_job process"
46
50
  task :restart, :roles => lambda { roles } do
47
- run "cd #{current_path};#{rails_env} script/delayed_job restart #{args}"
51
+ run "cd #{current_path};#{rails_env} #{delayed_job_command} restart #{args}"
48
52
  end
49
53
  end
50
54
  end
@@ -3,11 +3,7 @@ if defined?(ActiveRecord)
3
3
  yaml_as "tag:ruby.yaml.org,2002:ActiveRecord"
4
4
 
5
5
  def self.yaml_new(klass, tag, val)
6
- if ActiveRecord::VERSION::MAJOR == 3
7
- klass.unscoped.find(val['attributes'][klass.primary_key])
8
- else # Rails 2
9
- klass.with_exclusive_scope { klass.find(val['attributes'][klass.primary_key]) }
10
- end
6
+ klass.unscoped.find(val['attributes'][klass.primary_key])
11
7
  rescue ActiveRecord::RecordNotFound
12
8
  raise Delayed::DeserializationError, "ActiveRecord::RecordNotFound, class: #{klass} , primary key: #{val['attributes'][klass.primary_key]} "
13
9
  end
@@ -20,6 +20,9 @@ module Delayed
20
20
  :default_priority, :sleep_delay, :logger, :delay_jobs, :queues,
21
21
  :read_ahead, :plugins, :destroy_failed_jobs
22
22
 
23
+ # Named queue into which jobs are enqueued by default
24
+ cattr_accessor :default_queue_name
25
+
23
26
  cattr_reader :backend
24
27
 
25
28
  # name_prefix is ignored if name is set directly
@@ -185,7 +188,7 @@ module Delayed
185
188
  say "#{job.name} completed after %.4f" % runtime
186
189
  return true # did work
187
190
  rescue DeserializationError => error
188
- job.last_error = "{#{error.message}\n#{error.backtrace.join("\n")}"
191
+ job.last_error = "#{error.message}\n#{error.backtrace.join("\n")}"
189
192
  failed(job)
190
193
  rescue Exception => error
191
194
  self.class.lifecycle.run_callbacks(:error, self, job){ handle_failed_job(job, error) }
@@ -226,7 +229,7 @@ module Delayed
226
229
  protected
227
230
 
228
231
  def handle_failed_job(job, error)
229
- job.last_error = "{#{error.message}\n#{error.backtrace.join("\n")}"
232
+ job.last_error = "#{error.message}\n#{error.backtrace.join("\n")}"
230
233
  say "#{job.name} failed with #{error.class.name}: #{error.message} - #{job.attempts} failed attempts", Logger::ERROR
231
234
  reschedule(job)
232
235
  end
@@ -12,7 +12,7 @@ describe Delayed::Lifecycle do
12
12
  lifecycle.before(:execute, &callback)
13
13
  end
14
14
 
15
- it 'should execute before wrapped block' do
15
+ it "executes before wrapped block" do
16
16
  callback.should_receive(:call).with(*arguments).ordered
17
17
  behavior.should_receive(:inside!).ordered
18
18
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
@@ -24,7 +24,7 @@ describe Delayed::Lifecycle do
24
24
  lifecycle.after(:execute, &callback)
25
25
  end
26
26
 
27
- it 'should execute after wrapped block' do
27
+ it "executes after wrapped block" do
28
28
  behavior.should_receive(:inside!).ordered
29
29
  callback.should_receive(:call).with(*arguments).ordered
30
30
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
@@ -40,14 +40,14 @@ describe Delayed::Lifecycle do
40
40
  end
41
41
  end
42
42
 
43
- it 'should before and after wrapped block' do
43
+ it "wraps a block" do
44
44
  behavior.should_receive(:before!).ordered
45
45
  behavior.should_receive(:inside!).ordered
46
46
  behavior.should_receive(:after!).ordered
47
47
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
48
48
  end
49
49
 
50
- it "should execute multiple callbacks in order" do
50
+ it "executes multiple callbacks in order" do
51
51
  behavior.should_receive(:one).ordered
52
52
  behavior.should_receive(:two).ordered
53
53
  behavior.should_receive(:three).ordered
@@ -60,7 +60,7 @@ describe Delayed::Lifecycle do
60
60
  end
61
61
  end
62
62
 
63
- it "should raise if callback is executed with wrong number of parameters" do
63
+ it "raises if callback is executed with wrong number of parameters" 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
@@ -7,39 +7,39 @@ describe Delayed::MessageSending do
7
7
  handle_asynchronously :tell!
8
8
  end
9
9
 
10
- it "should alias original method" do
11
- Story.new.should respond_to(:tell_without_delay!)
12
- Story.new.should respond_to(:tell_with_delay!)
10
+ it "aliases original method" do
11
+ expect(Story.new).to respond_to(:tell_without_delay!)
12
+ expect(Story.new).to respond_to(:tell_with_delay!)
13
13
  end
14
14
 
15
- it "should create a PerformableMethod" do
15
+ it "creates a PerformableMethod" do
16
16
  story = Story.create
17
- lambda {
17
+ expect {
18
18
  job = story.tell!(1)
19
- job.payload_object.class.should == Delayed::PerformableMethod
20
- job.payload_object.method_name.should == :tell_without_delay!
21
- job.payload_object.args.should == [1]
22
- }.should change { Delayed::Job.count }
19
+ expect(job.payload_object.class).to eq(Delayed::PerformableMethod)
20
+ expect(job.payload_object.method_name).to eq(:tell_without_delay!)
21
+ expect(job.payload_object.args).to eq([1])
22
+ }.to change { Delayed::Job.count }
23
23
  end
24
24
 
25
- describe 'with options' do
25
+ describe "with options" do
26
26
  class Fable
27
27
  cattr_accessor :importance
28
28
  def tell;end
29
29
  handle_asynchronously :tell, :priority => Proc.new { self.importance }
30
30
  end
31
31
 
32
- it 'should set the priority based on the Fable importance' do
32
+ it "sets the priority based on the Fable importance" do
33
33
  Fable.importance = 10
34
34
  job = Fable.new.tell
35
- job.priority.should == 10
35
+ expect(job.priority).to eq(10)
36
36
 
37
37
  Fable.importance = 20
38
38
  job = Fable.new.tell
39
- job.priority.should == 20
39
+ expect(job.priority).to eq(20)
40
40
  end
41
41
 
42
- describe 'using a proc with parameters' do
42
+ describe "using a proc with parameters" do
43
43
  class Yarn
44
44
  attr_accessor :importance
45
45
  def spin
@@ -47,12 +47,12 @@ describe Delayed::MessageSending do
47
47
  handle_asynchronously :spin, :priority => Proc.new {|y| y.importance }
48
48
  end
49
49
 
50
- it 'should set the priority based on the Fable importance' do
50
+ it "sets the priority based on the Fable importance" do
51
51
  job = Yarn.new.tap {|y| y.importance = 10 }.spin
52
- job.priority.should == 10
52
+ expect(job.priority).to eq(10)
53
53
 
54
54
  job = Yarn.new.tap {|y| y.importance = 20 }.spin
55
- job.priority.should == 20
55
+ expect(job.priority).to eq(20)
56
56
  end
57
57
  end
58
58
  end
@@ -67,47 +67,54 @@ describe Delayed::MessageSending do
67
67
  end
68
68
  end
69
69
 
70
- it "should create a new PerformableMethod job" do
71
- lambda {
70
+ it "creates a new PerformableMethod job" do
71
+ expect {
72
72
  job = "hello".delay.count('l')
73
- job.payload_object.class.should == Delayed::PerformableMethod
74
- job.payload_object.method_name.should == :count
75
- job.payload_object.args.should == ['l']
76
- }.should change { Delayed::Job.count }.by(1)
73
+ expect(job.payload_object.class).to eq(Delayed::PerformableMethod)
74
+ expect(job.payload_object.method_name).to eq(:count)
75
+ expect(job.payload_object.args).to eq(['l'])
76
+ }.to change { Delayed::Job.count }.by(1)
77
77
  end
78
78
 
79
- it "should set default priority" do
79
+ it "sets default priority" do
80
80
  Delayed::Worker.default_priority = 99
81
81
  job = FairyTail.delay.to_s
82
- job.priority.should == 99
82
+ expect(job.priority).to eq(99)
83
83
  Delayed::Worker.default_priority = 0
84
84
  end
85
85
 
86
- it "should set job options" do
86
+ it "sets default queue name" do
87
+ Delayed::Worker.default_queue_name = 'abbazabba'
88
+ job = FairyTail.delay.to_s
89
+ expect(job.queue).to eq('abbazabba')
90
+ Delayed::Worker.default_queue_name = nil
91
+ end
92
+
93
+ it "sets job options" do
87
94
  run_at = Time.parse('2010-05-03 12:55 AM')
88
95
  job = FairyTail.delay(:priority => 20, :run_at => run_at).to_s
89
- job.run_at.should == run_at
90
- job.priority.should == 20
96
+ expect(job.run_at).to eq(run_at)
97
+ expect(job.priority).to eq(20)
91
98
  end
92
99
 
93
- it "should not delay the job when delay_jobs is false" do
100
+ it "does not delay the job when delay_jobs is false" do
94
101
  Delayed::Worker.delay_jobs = false
95
102
  fairy_tail = FairyTail.new
96
- lambda {
97
- lambda {
103
+ expect {
104
+ expect {
98
105
  fairy_tail.delay.tell
99
- }.should change(fairy_tail, :happy_ending).from(nil).to(true)
100
- }.should_not change { Delayed::Job.count }
106
+ }.to change(fairy_tail, :happy_ending).from(nil).to(true)
107
+ }.not_to change { Delayed::Job.count }
101
108
  end
102
109
 
103
- it "should delay the job when delay_jobs is true" do
110
+ it "does delay the job when delay_jobs is true" do
104
111
  Delayed::Worker.delay_jobs = true
105
112
  fairy_tail = FairyTail.new
106
- lambda {
107
- lambda {
113
+ expect {
114
+ expect {
108
115
  fairy_tail.delay.tell
109
- }.should_not change(fairy_tail, :happy_ending)
110
- }.should change { Delayed::Job.count }.by(1)
116
+ }.not_to change(fairy_tail, :happy_ending)
117
+ }.to change { Delayed::Job.count }.by(1)
111
118
  end
112
119
  end
113
120
  end
@@ -9,27 +9,27 @@ end
9
9
 
10
10
  describe ActionMailer::Base do
11
11
  describe "delay" do
12
- it "should enqueue a PerformableEmail job" do
13
- lambda {
12
+ it "enqueues a PerformableEmail job" do
13
+ expect {
14
14
  job = MyMailer.delay.signup('john@example.com')
15
- job.payload_object.class.should == Delayed::PerformableMailer
16
- job.payload_object.method_name.should == :signup
17
- job.payload_object.args.should == ['john@example.com']
18
- }.should change { Delayed::Job.count }.by(1)
15
+ expect(job.payload_object.class).to eq(Delayed::PerformableMailer)
16
+ expect(job.payload_object.method_name).to eq(:signup)
17
+ expect(job.payload_object.args).to eq(['john@example.com'])
18
+ }.to change { Delayed::Job.count }.by(1)
19
19
  end
20
20
  end
21
21
 
22
22
  describe "delay on a mail object" do
23
- it "should raise an exception" do
24
- lambda {
23
+ it "raises an exception" do
24
+ expect {
25
25
  MyMailer.signup('john@example.com').delay
26
- }.should raise_error(RuntimeError)
26
+ }.to raise_error(RuntimeError)
27
27
  end
28
28
  end
29
29
 
30
30
  describe Delayed::PerformableMailer do
31
31
  describe "perform" do
32
- it "should call the method and #deliver on the mailer" do
32
+ it "calls the method and #deliver on the mailer" do
33
33
  email = mock('email', :deliver => true)
34
34
  mailer_class = mock('MailerClass', :signup => email)
35
35
  mailer = Delayed::PerformableMailer.new(mailer_class, :signup, ['john@example.com'])
@@ -11,37 +11,37 @@ describe Delayed::PerformableMethod do
11
11
  @method.object = nil
12
12
  end
13
13
 
14
- it "should be a no-op if object is nil" do
15
- lambda { @method.perform }.should_not raise_error
14
+ it "does nothing if object is nil" do
15
+ expect{@method.perform}.not_to raise_error
16
16
  end
17
17
  end
18
18
 
19
- it "should call the method on the object" do
19
+ it "calls the method on the object" do
20
20
  @method.object.should_receive(:count).with('o')
21
21
  @method.perform
22
22
  end
23
23
  end
24
24
 
25
- it "should raise a NoMethodError if target method doesn't exist" do
26
- lambda {
25
+ it "raises a NoMethodError if target method doesn't exist" do
26
+ expect {
27
27
  Delayed::PerformableMethod.new(Object, :method_that_does_not_exist, [])
28
- }.should raise_error(NoMethodError)
28
+ }.to raise_error(NoMethodError)
29
29
  end
30
30
 
31
- it "should not raise NoMethodError if target method is private" do
31
+ it "does not raise NoMethodError if target method is private" do
32
32
  clazz = Class.new do
33
33
  def private_method
34
34
  end
35
35
  private :private_method
36
36
  end
37
- lambda {
37
+ expect {
38
38
  Delayed::PerformableMethod.new(clazz.new, :private_method, [])
39
- }.should_not raise_error(NoMethodError)
39
+ }.not_to raise_error(NoMethodError)
40
40
  end
41
41
 
42
42
  describe "hooks" do
43
43
  %w(enqueue before after success).each do |hook|
44
- it "should delegate #{hook} hook to object" do
44
+ it "delegates #{hook} hook to object" do
45
45
  story = Story.create
46
46
  story.should_receive(hook).with(an_instance_of(Delayed::Job))
47
47
  story.delay.tell.invoke_job
@@ -49,7 +49,7 @@ describe Delayed::PerformableMethod do
49
49
  end
50
50
 
51
51
  %w(before after success).each do |hook|
52
- it "should delegate #{hook} hook to object when delay_jobs = false" do
52
+ it "delegates #{hook} hook to object when delay_jobs = false" do
53
53
  Delayed::Worker.delay_jobs = false
54
54
  story = Story.create
55
55
  story.should_receive(hook).with(an_instance_of(Delayed::Job))
@@ -57,28 +57,28 @@ describe Delayed::PerformableMethod do
57
57
  end
58
58
  end
59
59
 
60
- it "should delegate error hook to object" do
60
+ it "delegates error hook to object" do
61
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
- lambda { story.delay.tell.invoke_job }.should raise_error
64
+ expect{story.delay.tell.invoke_job}.to raise_error
65
65
  end
66
66
 
67
- it "should delegate error hook to object when delay_jobs = false" do
67
+ it "delegates error hook to object when delay_jobs = false" do
68
68
  Delayed::Worker.delay_jobs = false
69
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
- lambda { story.delay.tell }.should raise_error
72
+ expect{story.delay.tell}.to raise_error
73
73
  end
74
74
 
75
- it "should delegate failure hook to object" do
75
+ it "delegates failure hook to object" do
76
76
  method = Delayed::PerformableMethod.new("object", :size, [])
77
77
  method.object.should_receive(:failure)
78
78
  method.failure
79
79
  end
80
80
 
81
- it "should delegate failure hook to object when delay_jobs = false" do
81
+ it "delegates 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)
@@ -50,4 +50,8 @@ RSpec.configure do |config|
50
50
  config.after(:each) do
51
51
  Delayed::Worker.reset
52
52
  end
53
+
54
+ config.expect_with :rspec do |c|
55
+ c.syntax = :expect
56
+ end
53
57
  end
@@ -4,10 +4,10 @@ describe Delayed::Backend::Test::Job do
4
4
  it_should_behave_like 'a delayed_job backend'
5
5
 
6
6
  describe "#reload" do
7
- it 'should cause the payload object to be reloaded' do
7
+ it "causes the payload object to be reloaded" do
8
8
  job = "foo".delay.length
9
9
  o = job.payload_object
10
- o.object_id.should_not == job.reload.payload_object.object_id
10
+ expect(o.object_id).not_to eq(job.reload.payload_object.object_id)
11
11
  end
12
12
  end
13
13
  end
@@ -7,13 +7,34 @@ describe Delayed::Worker do
7
7
  Delayed::Worker.backend = @clazz
8
8
  end
9
9
 
10
- it "should set the Delayed::Job constant to the backend" do
11
- Delayed::Job.should == @clazz
10
+ it "sets the Delayed::Job constant to the backend" do
11
+ expect(Delayed::Job).to eq(@clazz)
12
12
  end
13
13
 
14
- it "should set backend with a symbol" do
14
+ it "sets backend with a symbol" do
15
15
  Delayed::Worker.backend = :test
16
- Delayed::Worker.backend.should == Delayed::Backend::Test::Job
16
+ expect(Delayed::Worker.backend).to eq(Delayed::Backend::Test::Job)
17
+ end
18
+ end
19
+
20
+ context "worker read-ahead" do
21
+ before do
22
+ @read_ahead = Delayed::Worker.read_ahead
23
+ end
24
+
25
+ after do
26
+ Delayed::Worker.read_ahead = @read_ahead
27
+ end
28
+
29
+ it "reads five jobs" do
30
+ Delayed::Job.should_receive(:find_available).with(anything, 5, anything).and_return([])
31
+ Delayed::Job.reserve(Delayed::Worker.new)
32
+ end
33
+
34
+ it "reads a configurable number of jobs" do
35
+ Delayed::Worker.read_ahead = 15
36
+ Delayed::Job.should_receive(:find_available).with(anything, Delayed::Worker.read_ahead, anything).and_return([])
37
+ Delayed::Job.reserve(Delayed::Worker.new)
17
38
  end
18
39
  end
19
40
  end