delayed_job 4.0.0 → 4.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 44f2fddb4257788893e27e7fe18e159748132d45
4
+ data.tar.gz: ed334f09c9f6d3c9ff987a04f5131d4d8bf1286a
5
+ SHA512:
6
+ metadata.gz: a43f95acb0fd7b4d1eacadc523dc470f08aa290ccf2b224819a77bd60acd8b363665bd7992372420d6d382b6ca6ead131a725f0ee638abce35405900748e2612
7
+ data.tar.gz: ff353fb2e6115237541411a67aee47381120fda1a20d56a70a0a50a51a4cc56c21e0f7e3935c1869fbcf6dbb8051199ae95e3eec68d4208f0a6c3e3f3f252cd5
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ 4.0.1 - 2014-04-12
2
+ ==================
3
+ * Update gemspec for Rails 4.1
4
+ * Make logger calls more universal
5
+ * Check that records are persisted? instead of new_record?
6
+
1
7
  4.0.0 - 2013-07-30
2
8
  ==================
3
9
  * Rails 4 compatibility
data/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  Delayed::Job
2
2
  ============
3
3
  [![Gem Version](https://badge.fury.io/rb/delayed_job.png)][gem]
4
- [![Build Status](https://secure.travis-ci.org/collectiveidea/delayed_job.png?branch=master)][travis]
4
+ [![Build Status](https://travis-ci.org/collectiveidea/delayed_job.png?branch=master)][travis]
5
5
  [![Dependency Status](https://gemnasium.com/collectiveidea/delayed_job.png?travis)][gemnasium]
6
6
  [![Code Climate](https://codeclimate.com/github/collectiveidea/delayed_job.png)][codeclimate]
7
7
  [![Coverage Status](https://coveralls.io/repos/collectiveidea/delayed_job/badge.png?branch=master)][coveralls]
8
8
 
9
9
  [gem]: https://rubygems.org/gems/delayed_job
10
- [travis]: http://travis-ci.org/collectiveidea/delayed_job
10
+ [travis]: https://travis-ci.org/collectiveidea/delayed_job
11
11
  [gemnasium]: https://gemnasium.com/collectiveidea/delayed_job
12
12
  [codeclimate]: https://codeclimate.com/github/collectiveidea/delayed_job
13
13
  [coveralls]: https://coveralls.io/r/collectiveidea/delayed_job
@@ -36,7 +36,7 @@ delayed_job 3.0.0 only supports Rails 3.0+. See the [2.0
36
36
  branch](https://github.com/collectiveidea/delayed_job/tree/v2.0) for Rails 2.
37
37
 
38
38
  delayed_job supports multiple backends for storing the job queue. [See the wiki
39
- for other backends](http://wiki.github.com/collectiveidea/delayed_job/backends).
39
+ for other backends](https://github.com/collectiveidea/delayed_job/wiki/Backends).
40
40
 
41
41
  If you plan to use delayed_job with Active Record, add `delayed_job_active_record` to your `Gemfile`.
42
42
 
@@ -58,6 +58,10 @@ running the following command:
58
58
  rails generate delayed_job:active_record
59
59
  rake db:migrate
60
60
 
61
+ Rails 4
62
+ =======
63
+ If you are using the protected_attributes gem, it must appear before delayed_job in your gemfile.
64
+
61
65
  Upgrading from 2.x to 3.0.0 on Active Record
62
66
  ============================================
63
67
  Delayed Job 3.0.0 introduces a new column to the delayed_jobs table.
@@ -141,6 +145,9 @@ Notifier.signup(@user).deliver
141
145
 
142
146
  # with delayed_job
143
147
  Notifier.delay.signup(@user)
148
+
149
+ # with delayed_job running at a specific time
150
+ Notifier.delay(run_at: 5.minutes.from_now).signup(@user)
144
151
  ```
145
152
 
146
153
  Remove the `.deliver` method to make it work. It's not ideal, but it's the best
@@ -183,7 +190,7 @@ You can then do the following:
183
190
  RAILS_ENV=production script/delayed_job --queue=tracking start
184
191
  RAILS_ENV=production script/delayed_job --queues=mailers,tasks start
185
192
 
186
- # Runs all available jobs and the exits
193
+ # Runs all available jobs and then exits
187
194
  RAILS_ENV=production script/delayed_job start --exit-on-complete
188
195
  # or to run in the foreground
189
196
  RAILS_ENV=production script/delayed_job run --exit-on-complete
@@ -203,7 +210,7 @@ Work off queues by setting the `QUEUE` or `QUEUES` environment variable.
203
210
 
204
211
  QUEUE=tracking rake jobs:work
205
212
  QUEUES=mailers,tasks rake jobs:work
206
-
213
+
207
214
  Restarting delayed_job
208
215
  ======================
209
216
 
@@ -214,7 +221,7 @@ The following syntax will restart delayed jobs:
214
221
  To restart multiple delayed_job workers:
215
222
 
216
223
  RAILS_ENV=production script/delayed_job -n2 restart
217
-
224
+
218
225
  **Rails 4:** *replace script/delayed_job with bin/delayed_job*
219
226
 
220
227
 
@@ -224,7 +231,7 @@ Custom Jobs
224
231
  Jobs are simple ruby objects with a method called perform. Any object which responds to perform can be stuffed into the jobs table. Job objects are serialized to yaml so that they can later be resurrected by the job runner.
225
232
 
226
233
  ```ruby
227
- class NewsletterJob < Struct.new(:text, :emails)
234
+ NewsletterJob = Struct.new(:text, :emails) do
228
235
  def perform
229
236
  emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
230
237
  end
@@ -234,11 +241,11 @@ Delayed::Job.enqueue NewsletterJob.new('lorem ipsum...', Customers.find(:all).co
234
241
  ```
235
242
  To set a per-job max attempts that overrides the Delayed::Worker.max_attempts you can define a max_attempts method on the job
236
243
  ```ruby
237
- class NewsletterJob < Struct.new(:text, :emails)
244
+ NewsletterJob = Struct.new(:text, :emails) do
238
245
  def perform
239
246
  emails.each { |e| NewsletterMailer.deliver_text_to_email(text, e) }
240
247
  end
241
-
248
+
242
249
  def max_attempts
243
250
  return 3
244
251
  end
@@ -276,7 +283,7 @@ class ParanoidNewsletterJob < NewsletterJob
276
283
  Airbrake.notify(exception)
277
284
  end
278
285
 
279
- def failure
286
+ def failure(job)
280
287
  page_sysadmin_in_the_middle_of_the_night
281
288
  end
282
289
  end
data/delayed_job.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
 
3
3
  Gem::Specification.new do |spec|
4
- spec.add_dependency 'activesupport', ['>= 3.0', '< 4.1']
4
+ spec.add_dependency 'activesupport', ['>= 3.0', '< 4.2']
5
5
  spec.authors = ["Brandon Keepers", "Brian Ryckbost", "Chris Gaffney", "David Genord II", "Erik Michaels-Ober", "Matt Griffin", "Steve Richert", "Tobias Lütke"]
6
6
  spec.description = "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."
7
7
  spec.email = ['brian@collectiveidea.com']
@@ -13,5 +13,5 @@ Gem::Specification.new do |spec|
13
13
  spec.require_paths = ['lib']
14
14
  spec.summary = 'Database-backed asynchronous priority queue system -- Extracted from Shopify'
15
15
  spec.test_files = Dir.glob('spec/**/*')
16
- spec.version = '4.0.0'
16
+ spec.version = '4.0.1'
17
17
  end
@@ -116,7 +116,7 @@ shared_examples_for "a delayed_job backend" do
116
116
 
117
117
  it "invokes the enqueued job" do
118
118
  job = SimpleJob.new
119
- job.should_receive(:perform)
119
+ expect(job).to receive(:perform)
120
120
  described_class.enqueue job
121
121
  end
122
122
 
@@ -134,7 +134,7 @@ shared_examples_for "a delayed_job backend" do
134
134
  %w(before success after).each do |callback|
135
135
  it "calls #{callback} with job" do
136
136
  job = described_class.enqueue(CallbackJob.new)
137
- job.payload_object.should_receive(callback).with(job)
137
+ expect(job.payload_object).to receive(callback).with(job)
138
138
  job.invoke_job
139
139
  end
140
140
  end
@@ -148,7 +148,7 @@ shared_examples_for "a delayed_job backend" do
148
148
 
149
149
  it "calls the after callback with an error" do
150
150
  job = described_class.enqueue(CallbackJob.new)
151
- job.payload_object.should_receive(:perform).and_raise(RuntimeError.new("fail"))
151
+ expect(job.payload_object).to receive(:perform).and_raise(RuntimeError.new("fail"))
152
152
 
153
153
  expect{job.invoke_job}.to raise_error
154
154
  expect(CallbackJob.messages).to eq(["enqueue", "before", "error: RuntimeError", "after"])
@@ -156,7 +156,7 @@ shared_examples_for "a delayed_job backend" do
156
156
 
157
157
  it "calls error when before raises an error" do
158
158
  job = described_class.enqueue(CallbackJob.new)
159
- job.payload_object.should_receive(:before).and_raise(RuntimeError.new("fail"))
159
+ expect(job.payload_object).to receive(:before).and_raise(RuntimeError.new("fail"))
160
160
  expect{job.invoke_job}.to raise_error(RuntimeError)
161
161
  expect(CallbackJob.messages).to eq(["enqueue", "error: RuntimeError", "after"])
162
162
  end
@@ -175,7 +175,7 @@ shared_examples_for "a delayed_job backend" do
175
175
 
176
176
  it "raises a DeserializationError when the YAML.load raises argument error" do
177
177
  job = described_class.new :handler => "--- !ruby/struct:GoingToRaiseArgError {}"
178
- YAML.should_receive(:load).and_raise(ArgumentError)
178
+ expect(YAML).to receive(:load).and_raise(ArgumentError)
179
179
  expect{job.payload_object}.to raise_error(Delayed::DeserializationError)
180
180
  end
181
181
  end
@@ -399,35 +399,47 @@ shared_examples_for "a delayed_job backend" do
399
399
  end
400
400
 
401
401
  it "uses the max_retries value on the payload when defined" do
402
- @job.payload_object.stub(:max_attempts).and_return(99)
402
+ expect(@job.payload_object).to receive(:max_attempts).and_return(99)
403
403
  expect(@job.max_attempts).to eq(99)
404
404
  end
405
405
  end
406
406
 
407
407
  describe "yaml serialization" do
408
- it "reloads changed attributes" do
409
- story = Story.create(:text => 'hello')
410
- job = story.delay.tell
411
- story.update_attributes :text => 'goodbye'
412
- expect(job.reload.payload_object.object.text).to eq('goodbye')
413
- end
408
+ context "when serializing jobs" do
409
+ it "raises error ArgumentError for new records" do
410
+ story = Story.new(:text => 'hello')
411
+ if story.respond_to?(:new_record?)
412
+ expect {
413
+ story.delay.tell
414
+ }.to raise_error(ArgumentError, 'Jobs cannot be created for non-persisted records')
415
+ end
416
+ end
414
417
 
415
- it "raises error ArgumentError the record is not persisted" do
416
- story = Story.new(:text => 'hello')
417
- if story.respond_to?(:new_record?)
418
+ it "raises error ArgumentError for destroyed records" do
419
+ story = Story.create(:text => 'hello')
420
+ story.destroy
418
421
  expect {
419
422
  story.delay.tell
420
- }.to raise_error(ArgumentError, "Jobs cannot be created for records before they've been persisted")
423
+ }.to raise_error(ArgumentError, 'Jobs cannot be created for non-persisted records')
421
424
  end
422
425
  end
423
426
 
424
- it "raises deserialization error for destroyed records" do
425
- story = Story.create(:text => 'hello')
426
- job = story.delay.tell
427
- story.destroy
428
- expect {
429
- job.reload.payload_object
430
- }.to raise_error(Delayed::DeserializationError)
427
+ context "when reload jobs back" do
428
+ it "reloads changed attributes" do
429
+ story = Story.create(:text => 'hello')
430
+ job = story.delay.tell
431
+ story.update_attributes :text => 'goodbye'
432
+ expect(job.reload.payload_object.object.text).to eq('goodbye')
433
+ end
434
+
435
+ it "raises deserialization error for destroyed records" do
436
+ story = Story.create(:text => 'hello')
437
+ job = story.delay.tell
438
+ story.destroy
439
+ expect {
440
+ job.reload.payload_object
441
+ }.to raise_error(Delayed::DeserializationError)
442
+ end
431
443
  end
432
444
  end
433
445
 
@@ -504,8 +516,8 @@ shared_examples_for "a delayed_job backend" do
504
516
 
505
517
  it "does not fail when the triggered error doesn't have a message" do
506
518
  error_with_nil_message = StandardError.new
507
- error_with_nil_message.stub(:message).and_return nil
508
- @job.stub(:invoke_job).and_raise error_with_nil_message
519
+ expect(error_with_nil_message).to receive(:message).twice.and_return(nil)
520
+ expect(@job).to receive(:invoke_job).and_raise error_with_nil_message
509
521
  expect{worker.run(@job)}.not_to raise_error
510
522
  end
511
523
  end
@@ -519,27 +531,25 @@ shared_examples_for "a delayed_job backend" do
519
531
  context "when the job's payload has a #failure hook" do
520
532
  before do
521
533
  @job = Delayed::Job.create :payload_object => OnPermanentFailureJob.new
522
- expect(@job.payload_object).to respond_to :failure
534
+ expect(@job.payload_object).to respond_to(:failure)
523
535
  end
524
536
 
525
537
  it "runs that hook" do
526
- @job.payload_object.should_receive :failure
538
+ expect(@job.payload_object).to receive(:failure)
527
539
  worker.reschedule(@job)
528
540
  end
529
541
  end
530
542
 
531
543
  context "when the job's payload has no #failure hook" do
532
544
  # It's a little tricky to test this in a straightforward way,
533
- # because putting a should_not_receive expectation on
534
- # @job.payload_object.failure makes that object
535
- # incorrectly return true to
536
- # payload_object.respond_to? :failure, which is what
537
- # reschedule uses to decide whether to call failure.
538
- # So instead, we just make sure that the payload_object as it
539
- # already stands doesn't respond_to? failure, then
540
- # shove it through the iterated reschedule loop and make sure we
541
- # don't get a NoMethodError (caused by calling that nonexistent
542
- # failure method).
545
+ # because putting a not_to receive expectation on
546
+ # @job.payload_object.failure makes that object incorrectly return
547
+ # true to payload_object.respond_to? :failure, which is what
548
+ # reschedule uses to decide whether to call failure. So instead, we
549
+ # just make sure that the payload_object as it already stands doesn't
550
+ # respond_to? failure, then shove it through the iterated reschedule
551
+ # loop and make sure we don't get a NoMethodError (caused by calling
552
+ # that nonexistent failure method).
543
553
 
544
554
  before do
545
555
  expect(@job.payload_object).not_to respond_to(:failure)
@@ -557,12 +567,12 @@ shared_examples_for "a delayed_job backend" do
557
567
  it_should_behave_like "any failure more than Worker.max_attempts times"
558
568
 
559
569
  it "is destroyed if it failed more than Worker.max_attempts times" do
560
- @job.should_receive(:destroy)
570
+ expect(@job).to receive(:destroy)
561
571
  Delayed::Worker.max_attempts.times { worker.reschedule(@job) }
562
572
  end
563
573
 
564
574
  it "is not destroyed if failed fewer than Worker.max_attempts times" do
565
- @job.should_not_receive(:destroy)
575
+ expect(@job).not_to receive(:destroy)
566
576
  (Delayed::Worker.max_attempts - 1).times { worker.reschedule(@job) }
567
577
  end
568
578
  end
@@ -6,4 +6,6 @@ module Delayed
6
6
  "#{super} (Delayed::Worker.max_run_time is only #{Delayed::Worker.max_run_time.to_i} seconds)"
7
7
  end
8
8
  end
9
+
10
+ class FatalBackendError < Exception; end
9
11
  end
@@ -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 object.respond_to?(:new_record?) && object.new_record?
13
- raise(ArgumentError, 'Jobs cannot be created for records before they\'ve been persisted')
12
+ if object.respond_to?(:persisted?) && !object.persisted?
13
+ raise(ArgumentError, 'Jobs cannot be created for non-persisted records')
14
14
  end
15
15
 
16
16
  self.object = object
@@ -5,7 +5,7 @@ module Delayed
5
5
  class Railtie < Rails::Railtie
6
6
  initializer :after_initialize do
7
7
  ActiveSupport.on_load(:action_mailer) do
8
- ActionMailer::Base.send(:extend, Delayed::DelayMail)
8
+ ActionMailer::Base.extend(Delayed::DelayMail)
9
9
  end
10
10
  end
11
11
 
@@ -7,8 +7,9 @@ require 'logger'
7
7
  require 'benchmark'
8
8
 
9
9
  module Delayed
10
+
10
11
  class Worker
11
- DEFAULT_LOG_LEVEL = Logger::INFO
12
+ DEFAULT_LOG_LEVEL = 'info'
12
13
  DEFAULT_SLEEP_DELAY = 5
13
14
  DEFAULT_MAX_ATTEMPTS = 25
14
15
  DEFAULT_MAX_RUN_TIME = 4.hours
@@ -225,7 +226,7 @@ module Delayed
225
226
  job.unlock
226
227
  job.save!
227
228
  else
228
- job_say job, "REMOVED permanently because of #{job.attempts} consecutive failures", Logger::ERROR
229
+ job_say job, "REMOVED permanently because of #{job.attempts} consecutive failures", 'error'
229
230
  failed(job)
230
231
  end
231
232
  end
@@ -245,7 +246,13 @@ module Delayed
245
246
  def say(text, level = DEFAULT_LOG_LEVEL)
246
247
  text = "[Worker(#{name})] #{text}"
247
248
  puts text unless @quiet
248
- logger.add level, "#{Time.now.strftime('%FT%T%z')}: #{text}" if logger
249
+ if logger
250
+ # TODO: Deprecate use of Fixnum log levels
251
+ if !level.is_a?(String)
252
+ level = Logger::Severity.constants.detect {|i| Logger::Severity.const_get(i) == level }.to_s.downcase
253
+ end
254
+ logger.send(level, "#{Time.now.strftime('%FT%T%z')}: #{text}")
255
+ end
249
256
  end
250
257
 
251
258
  def max_attempts(job)
@@ -256,7 +263,7 @@ module Delayed
256
263
 
257
264
  def handle_failed_job(job, error)
258
265
  job.last_error = "#{error.message}\n#{error.backtrace.join("\n")}"
259
- job_say job, "FAILED (#{job.attempts} prior attempts) with #{error.class.name}: #{error.message}", Logger::ERROR
266
+ job_say job, "FAILED (#{job.attempts} prior attempts) with #{error.class.name}: #{error.message}", 'error'
260
267
  reschedule(job)
261
268
  end
262
269
 
data/spec/helper.rb CHANGED
@@ -26,7 +26,7 @@ Delayed::Worker.backend = :test
26
26
  ActiveSupport::Dependencies.autoload_paths << File.dirname(__FILE__)
27
27
 
28
28
  # Add this to simulate Railtie initializer being executed
29
- ActionMailer::Base.send(:extend, Delayed::DelayMail)
29
+ ActionMailer::Base.extend(Delayed::DelayMail)
30
30
 
31
31
 
32
32
  # Used to test interactions between DJ and an ORM
@@ -13,8 +13,8 @@ describe Delayed::Lifecycle do
13
13
  end
14
14
 
15
15
  it "executes before wrapped block" do
16
- callback.should_receive(:call).with(*arguments).ordered
17
- behavior.should_receive(:inside!).ordered
16
+ expect(callback).to receive(:call).with(*arguments).ordered
17
+ expect(behavior).to receive(:inside!).ordered
18
18
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
19
19
  end
20
20
  end
@@ -25,8 +25,8 @@ describe Delayed::Lifecycle do
25
25
  end
26
26
 
27
27
  it "executes after wrapped block" do
28
- behavior.should_receive(:inside!).ordered
29
- callback.should_receive(:call).with(*arguments).ordered
28
+ expect(behavior).to receive(:inside!).ordered
29
+ expect(callback).to receive(:call).with(*arguments).ordered
30
30
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
31
31
  end
32
32
  end
@@ -41,16 +41,16 @@ describe Delayed::Lifecycle do
41
41
  end
42
42
 
43
43
  it "wraps a block" do
44
- behavior.should_receive(:before!).ordered
45
- behavior.should_receive(:inside!).ordered
46
- behavior.should_receive(:after!).ordered
44
+ expect(behavior).to receive(:before!).ordered
45
+ expect(behavior).to receive(:inside!).ordered
46
+ expect(behavior).to receive(:after!).ordered
47
47
  lifecycle.run_callbacks :execute, *arguments, &wrapped_block
48
48
  end
49
49
 
50
50
  it "executes multiple callbacks in order" do
51
- behavior.should_receive(:one).ordered
52
- behavior.should_receive(:two).ordered
53
- behavior.should_receive(:three).ordered
51
+ expect(behavior).to receive(:one).ordered
52
+ expect(behavior).to receive(:two).ordered
53
+ expect(behavior).to receive(:three).ordered
54
54
 
55
55
  lifecycle.around(:execute) { |*args, &block| behavior.one; block.call(*args) }
56
56
  lifecycle.around(:execute) { |*args, &block| behavior.two; block.call(*args) }
@@ -34,8 +34,8 @@ describe ActionMailer::Base do
34
34
  mailer_class = double('MailerClass', :signup => email)
35
35
  mailer = Delayed::PerformableMailer.new(mailer_class, :signup, ['john@example.com'])
36
36
 
37
- mailer_class.should_receive(:signup).with('john@example.com')
38
- email.should_receive(:deliver)
37
+ expect(mailer_class).to receive(:signup).with('john@example.com')
38
+ expect(email).to receive(:deliver)
39
39
  mailer.perform
40
40
  end
41
41
  end
@@ -17,7 +17,7 @@ describe Delayed::PerformableMethod do
17
17
  end
18
18
 
19
19
  it "calls the method on the object" do
20
- @method.object.should_receive(:count).with('o')
20
+ expect(@method.object).to receive(:count).with('o')
21
21
  @method.perform
22
22
  end
23
23
  end
@@ -45,7 +45,7 @@ describe Delayed::PerformableMethod do
45
45
  story = Story.create
46
46
  job = story.delay.tell
47
47
 
48
- story.should_receive(hook).with(job)
48
+ expect(story).to receive(hook).with(job)
49
49
  job.invoke_job
50
50
  end
51
51
  end
@@ -55,34 +55,34 @@ describe Delayed::PerformableMethod do
55
55
  story = Story.create
56
56
  job = story.delay.tell
57
57
 
58
- story.should_receive(hook).with(job)
58
+ expect(story).to receive(hook).with(job)
59
59
  job.invoke_job
60
60
  end
61
61
  end
62
62
 
63
63
  it "delegates enqueue hook to object" do
64
64
  story = Story.create
65
- story.should_receive(:enqueue).with(an_instance_of(Delayed::Job))
65
+ expect(story).to receive(:enqueue).with(an_instance_of(Delayed::Job))
66
66
  story.delay.tell
67
67
  end
68
68
 
69
69
  it "delegates error hook to object" do
70
70
  story = Story.create
71
- story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
72
- story.should_receive(:tell).and_raise(RuntimeError)
71
+ expect(story).to receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
72
+ expect(story).to receive(:tell).and_raise(RuntimeError)
73
73
  expect { story.delay.tell.invoke_job }.to raise_error
74
74
  end
75
75
 
76
76
  it "delegates error hook to object when delay_jobs = false" do
77
77
  story = Story.create
78
- story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
79
- story.should_receive(:tell).and_raise(RuntimeError)
78
+ expect(story).to receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
79
+ expect(story).to receive(:tell).and_raise(RuntimeError)
80
80
  expect { story.delay.tell.invoke_job }.to raise_error
81
81
  end
82
82
 
83
83
  it "delegates failure hook to object" do
84
84
  method = Delayed::PerformableMethod.new("object", :size, [])
85
- method.object.should_receive(:failure)
85
+ expect(method.object).to receive(:failure)
86
86
  method.failure
87
87
  end
88
88
 
@@ -98,7 +98,7 @@ describe Delayed::PerformableMethod do
98
98
  %w(before after success).each do |hook|
99
99
  it "delegates #{hook} hook to object" do
100
100
  story = Story.create
101
- story.should_receive(hook).with(an_instance_of(Delayed::Job))
101
+ expect(story).to receive(hook).with(an_instance_of(Delayed::Job))
102
102
  story.delay.tell
103
103
  end
104
104
  end
@@ -106,29 +106,29 @@ describe Delayed::PerformableMethod do
106
106
  %w(before after success).each do |hook|
107
107
  it "delegates #{hook} hook to object" do
108
108
  story = Story.create
109
- story.should_receive(hook).with(an_instance_of(Delayed::Job))
109
+ expect(story).to receive(hook).with(an_instance_of(Delayed::Job))
110
110
  story.delay.tell
111
111
  end
112
112
  end
113
113
 
114
114
  it "delegates error hook to object" do
115
115
  story = Story.create
116
- story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
117
- story.should_receive(:tell).and_raise(RuntimeError)
116
+ expect(story).to receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
117
+ expect(story).to receive(:tell).and_raise(RuntimeError)
118
118
  expect { story.delay.tell }.to raise_error
119
119
  end
120
120
 
121
121
  it "delegates error hook to object when delay_jobs = false" do
122
122
  story = Story.create
123
- story.should_receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
124
- story.should_receive(:tell).and_raise(RuntimeError)
123
+ expect(story).to receive(:error).with(an_instance_of(Delayed::Job), an_instance_of(RuntimeError))
124
+ expect(story).to receive(:tell).and_raise(RuntimeError)
125
125
  expect { story.delay.tell }.to raise_error
126
126
  end
127
127
 
128
128
  it "delegates failure hook to object when delay_jobs = false" do
129
129
  Delayed::Worker.delay_jobs = false
130
130
  method = Delayed::PerformableMethod.new("object", :size, [])
131
- method.object.should_receive(:failure)
131
+ expect(method.object).to receive(:failure)
132
132
  method.failure
133
133
  end
134
134
  end
data/spec/worker_spec.rb CHANGED
@@ -28,7 +28,7 @@ describe Delayed::Worker do
28
28
  end
29
29
 
30
30
  it "logs with job name and id" do
31
- @worker.should_receive(:say).
31
+ expect(@worker).to receive(:say).
32
32
  with('Job ExampleJob (id=123) message', Delayed::Worker::DEFAULT_LOG_LEVEL)
33
33
  @worker.job_say(@job, 'message')
34
34
  end
@@ -44,13 +44,13 @@ describe Delayed::Worker do
44
44
  end
45
45
 
46
46
  it "reads five jobs" do
47
- Delayed::Job.should_receive(:find_available).with(anything, 5, anything).and_return([])
47
+ expect(Delayed::Job).to receive(:find_available).with(anything, 5, anything).and_return([])
48
48
  Delayed::Job.reserve(Delayed::Worker.new)
49
49
  end
50
50
 
51
51
  it "reads a configurable number of jobs" do
52
52
  Delayed::Worker.read_ahead = 15
53
- Delayed::Job.should_receive(:find_available).with(anything, Delayed::Worker.read_ahead, anything).and_return([])
53
+ expect(Delayed::Job).to receive(:find_available).with(anything, Delayed::Worker.read_ahead, anything).and_return([])
54
54
  Delayed::Job.reserve(Delayed::Worker.new)
55
55
  end
56
56
  end
@@ -82,21 +82,68 @@ describe Delayed::Worker do
82
82
  end
83
83
 
84
84
  it "handles error during job reservation" do
85
- Delayed::Job.should_receive(:reserve).and_raise(Exception)
85
+ expect(Delayed::Job).to receive(:reserve).and_raise(Exception)
86
86
  Delayed::Worker.new.work_off
87
87
  end
88
88
 
89
89
  it "gives up after 10 backend failures" do
90
- Delayed::Job.stub(:reserve).and_raise(Exception)
90
+ expect(Delayed::Job).to receive(:reserve).exactly(10).times.and_raise(Exception)
91
91
  worker = Delayed::Worker.new
92
92
  9.times { worker.work_off }
93
- expect(lambda { worker.work_off }).to raise_exception
93
+ expect(lambda { worker.work_off }).to raise_exception Delayed::FatalBackendError
94
94
  end
95
95
 
96
96
  it "allows the backend to attempt recovery from reservation errors" do
97
- Delayed::Job.should_receive(:reserve).and_raise(Exception)
98
- Delayed::Job.should_receive(:recover_from).with(instance_of(Exception))
97
+ expect(Delayed::Job).to receive(:reserve).and_raise(Exception)
98
+ expect(Delayed::Job).to receive(:recover_from).with(instance_of(Exception))
99
99
  Delayed::Worker.new.work_off
100
100
  end
101
101
  end
102
+
103
+ context "#say" do
104
+ before(:each) do
105
+ @worker = Delayed::Worker.new
106
+ @worker.name = 'ExampleJob'
107
+ @worker.logger = double('job')
108
+ time = Time.now
109
+ Time.stub(:now).and_return(time)
110
+ @text = "Job executed"
111
+ @worker_name = "[Worker(ExampleJob)]"
112
+ @expected_time = time.strftime('%FT%T%z')
113
+ end
114
+
115
+ after(:each) do
116
+ @worker.logger = nil
117
+ end
118
+
119
+ shared_examples_for "a worker which logs on the correct severity" do |severity|
120
+ it "logs a message on the #{severity[:level].upcase} level given a string" do
121
+ expect(@worker.logger).to receive(:send).
122
+ with(severity[:level], "#{@expected_time}: #{@worker_name} #{@text}")
123
+ @worker.say(@text, severity[:level])
124
+ end
125
+
126
+ it "logs a message on the #{severity[:level].upcase} level given a fixnum" do
127
+ expect(@worker.logger).to receive(:send).
128
+ with(severity[:level], "#{@expected_time}: #{@worker_name} #{@text}")
129
+ @worker.say(@text, severity[:index])
130
+ end
131
+ end
132
+
133
+ severities = [ { index: 0, level: "debug" },
134
+ { index: 1, level: "info" },
135
+ { index: 2, level: "warn" },
136
+ { index: 3, level: "error" },
137
+ { index: 4, level: "fatal" },
138
+ { index: 5, level: "unknown" } ]
139
+ severities.each do |severity|
140
+ it_behaves_like "a worker which logs on the correct severity", severity
141
+ end
142
+
143
+ it "logs a message on the default log's level" do
144
+ expect(@worker.logger).to receive(:send).
145
+ with("info", "#{@expected_time}: #{@worker_name} #{@text}")
146
+ @worker.say(@text, Delayed::Worker::DEFAULT_LOG_LEVEL)
147
+ end
148
+ end
102
149
  end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
5
- prerelease:
4
+ version: 4.0.1
6
5
  platform: ruby
7
6
  authors:
8
7
  - Brandon Keepers
@@ -16,30 +15,28 @@ authors:
16
15
  autorequire:
17
16
  bindir: bin
18
17
  cert_chain: []
19
- date: 2013-07-30 00:00:00.000000000 Z
18
+ date: 2014-04-12 00:00:00.000000000 Z
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: activesupport
23
22
  requirement: !ruby/object:Gem::Requirement
24
- none: false
25
23
  requirements:
26
- - - ! '>='
24
+ - - ">="
27
25
  - !ruby/object:Gem::Version
28
26
  version: '3.0'
29
- - - <
27
+ - - "<"
30
28
  - !ruby/object:Gem::Version
31
- version: '4.1'
29
+ version: '4.2'
32
30
  type: :runtime
33
31
  prerelease: false
34
32
  version_requirements: !ruby/object:Gem::Requirement
35
- none: false
36
33
  requirements:
37
- - - ! '>='
34
+ - - ">="
38
35
  - !ruby/object:Gem::Version
39
36
  version: '3.0'
40
- - - <
37
+ - - "<"
41
38
  - !ruby/object:Gem::Version
42
- version: '4.1'
39
+ version: '4.2'
43
40
  description: Delayed_job (or DJ) encapsulates the common pattern of asynchronously
44
41
  executing longer tasks in the background. It is a direct extraction from Shopify
45
42
  where the job table is responsible for a multitude of core tasks.
@@ -54,11 +51,11 @@ files:
54
51
  - LICENSE.md
55
52
  - README.md
56
53
  - Rakefile
57
- - delayed_job.gemspec
58
54
  - contrib/delayed_job.monitrc
59
55
  - contrib/delayed_job_multiple.monitrc
60
56
  - contrib/delayed_job_rails_4.monitrc
61
57
  - contrib/delayed_job_rails_4_multiple.monitrc
58
+ - delayed_job.gemspec
62
59
  - lib/delayed/backend/base.rb
63
60
  - lib/delayed/backend/shared_spec.rb
64
61
  - lib/delayed/command.rb
@@ -101,33 +98,26 @@ files:
101
98
  homepage: http://github.com/collectiveidea/delayed_job
102
99
  licenses:
103
100
  - MIT
101
+ metadata: {}
104
102
  post_install_message:
105
103
  rdoc_options: []
106
104
  require_paths:
107
105
  - lib
108
106
  required_ruby_version: !ruby/object:Gem::Requirement
109
- none: false
110
107
  requirements:
111
- - - ! '>='
108
+ - - ">="
112
109
  - !ruby/object:Gem::Version
113
110
  version: '0'
114
- segments:
115
- - 0
116
- hash: 3979399263094595498
117
111
  required_rubygems_version: !ruby/object:Gem::Requirement
118
- none: false
119
112
  requirements:
120
- - - ! '>='
113
+ - - ">="
121
114
  - !ruby/object:Gem::Version
122
115
  version: '0'
123
- segments:
124
- - 0
125
- hash: 3979399263094595498
126
116
  requirements: []
127
117
  rubyforge_project:
128
- rubygems_version: 1.8.23
118
+ rubygems_version: 2.2.2
129
119
  signing_key:
130
- specification_version: 3
120
+ specification_version: 4
131
121
  summary: Database-backed asynchronous priority queue system -- Extracted from Shopify
132
122
  test_files:
133
123
  - spec/autoloaded/clazz.rb