delayed_job 4.1.2 → 4.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4f13f44eb18f5903178447ab50ddd453895632b3
4
- data.tar.gz: 20c22a692ca3d8084a85fdb3e401f209d822eb3b
3
+ metadata.gz: 5e2fe748c9a94faf96700fa8f87466b6fe7fd079
4
+ data.tar.gz: 21d55a1f49084db05123ad5573711ef7a52f7c29
5
5
  SHA512:
6
- metadata.gz: a2d9edf1e02e8fd824a5016a7761e049b0b3ae90509231d021858475dbfa7fe5695cf3a150b4564fe998e0d6fa11e39bde9017c0022ae899452a46f52d192c58
7
- data.tar.gz: a0a6875d0e951fbd0a3f442e2b699605bb36074b4c38ececaec501b721717ea64800fa191ed1ebae1b528ba7e8f7d8caee1c53115dc741870e7dc034ed916211
6
+ metadata.gz: cadfae1e2a548b451dc336f033ae671bd005c5b17fa311c5af3a306851b6d5642fcc88bee79ebbc9826032e9dccdf5f58eb0315de63e3357106987f496009f69
7
+ data.tar.gz: 2a07509ecd676d248ca983a3ba87062cf1b11a8bdc67f0cd63ab91a2c975e8f840b323bba8ae9596aa15db2435702484763acd7688adaf39b492910fffead165
@@ -1,4 +1,14 @@
1
+ 4.1.3 - 2017-05-26
2
+ =================
3
+ * Don't mutate the options hash (#877)
4
+ * Log an error message when a deserialization error occurs (#894)
5
+ * Adding the queue name to the log output (#917)
6
+ * Don't include ClassMethods with MessageSending (#924)
7
+ * Fix YAML deserialization error if original object is soft-deleted (#947)
8
+ * Add support for Rails 5.1 (#982)
9
+
1
10
  4.1.2 - 2016-05-16
11
+ ==================
2
12
  * Added Delayed::Worker.queue_attributes
3
13
  * Limit what we require in ActiveSupport
4
14
  * Fix pid file creation when there is no tmp directory
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  **If you're viewing this at https://github.com/collectiveidea/delayed_job,
2
2
  you're reading the documentation for the master branch.
3
3
  [View documentation for the latest release
4
- (4.1.2).](https://github.com/collectiveidea/delayed_job/tree/v4.1.2)**
4
+ (4.1.3).](https://github.com/collectiveidea/delayed_job/tree/v4.1.3)**
5
5
 
6
6
  Delayed::Job
7
7
  ============
@@ -37,8 +37,7 @@ multitude of core tasks. Amongst those tasks are:
37
37
 
38
38
  Installation
39
39
  ============
40
- delayed_job 3.0.0 only supports Rails 3.0+. See the [2.0
41
- branch](https://github.com/collectiveidea/delayed_job/tree/v2.0) for Rails 2.
40
+ delayed_job 3.0.0 only supports Rails 3.0+.
42
41
 
43
42
  delayed_job supports multiple backends for storing the job queue. [See the wiki
44
43
  for other backends](https://github.com/collectiveidea/delayed_job/wiki/Backends).
@@ -220,6 +219,12 @@ Configured queue priorities can be overriden by passing priority to the delay me
220
219
  object.delay(:queue => 'high_priority', priority: 0).method
221
220
  ```
222
221
 
222
+ You can start processes to only work certain queues with the `queue` and `queues`
223
+ options defined below. Processes started without specifying a queue will run jobs
224
+ from **any** queue. To effectively have a process that runs jobs where a queue is not
225
+ specified, set a default queue name with `Delayed::Worker.default_queue_name` and
226
+ have the processes run that queue.
227
+
223
228
  Running Jobs
224
229
  ============
225
230
  `script/delayed_job` can be used to manage a background process which will
@@ -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', '< 5.1']
4
+ spec.add_dependency 'activesupport', ['>= 3.0', '< 5.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.1.2'
16
+ spec.version = '4.1.3'
17
17
  end
@@ -30,16 +30,13 @@ module Delayed
30
30
  end
31
31
 
32
32
  # Allow the backend to attempt recovery from reserve errors
33
- def recover_from(_error)
34
- end
33
+ def recover_from(_error); end
35
34
 
36
35
  # Hook method that is called before a new worker is forked
37
- def before_fork
38
- end
36
+ def before_fork; end
39
37
 
40
38
  # Hook method that is called after a new worker is forked
41
- def after_fork
42
- end
39
+ def after_fork; end
43
40
 
44
41
  def work_off(num = 100)
45
42
  warn '[DEPRECATION] `Delayed::Job.work_off` is deprecated. Use `Delayed::Worker.new.work_off instead.'
@@ -101,7 +98,7 @@ module Delayed
101
98
  def hook(name, *args)
102
99
  if payload_object.respond_to?(name)
103
100
  method = payload_object.method(name)
104
- method.arity == 0 ? method.call : method.call(self, *args)
101
+ method.arity.zero? ? method.call : method.call(self, *args)
105
102
  end
106
103
  rescue DeserializationError # rubocop:disable HandleExceptions
107
104
  end
@@ -4,7 +4,7 @@ module Delayed
4
4
  attr_reader :options, :args
5
5
 
6
6
  def initialize(*args)
7
- @options = args.extract_options!
7
+ @options = args.extract_options!.dup
8
8
  @args = args
9
9
  end
10
10
 
@@ -42,9 +42,11 @@ module Delayed
42
42
  options[:run_at] = args[1]
43
43
  end
44
44
 
45
+ # rubocop:disable GuardClause
45
46
  unless options[:payload_object].respond_to?(:perform)
46
47
  raise ArgumentError, 'Cannot enqueue items which do not respond to perform'
47
48
  end
49
+ # rubocop:enabled GuardClause
48
50
  end
49
51
  end
50
52
  end
@@ -113,6 +113,12 @@ shared_examples_for 'a delayed_job backend' do
113
113
  job = described_class.enqueue M::ModuleJob.new
114
114
  expect { job.invoke_job }.to change { M::ModuleJob.runs }.from(0).to(1)
115
115
  end
116
+
117
+ it 'does not mutate the options hash' do
118
+ options = {:priority => 1}
119
+ described_class.enqueue SimpleJob.new, options
120
+ expect(options).to eq(:priority => 1)
121
+ end
116
122
  end
117
123
 
118
124
  context 'with delay_jobs = false' do
@@ -77,8 +77,11 @@ module Delayed
77
77
  opt.on('--exit-on-complete', 'Exit when no more jobs are available to run. This will exit if all jobs are scheduled to run in the future.') do
78
78
  @options[:exit_on_complete] = true
79
79
  end
80
+ opt.on('--daemon-options a, b, c', Array, 'options to be passed through to daemons gem') do |daemon_options|
81
+ @daemon_options = daemon_options
82
+ end
80
83
  end
81
- @args = opts.parse!(args)
84
+ @args = opts.parse!(args) + (@daemon_options || [])
82
85
  end
83
86
 
84
87
  def daemonize # rubocop:disable PerceivedComplexity
@@ -88,11 +91,13 @@ module Delayed
88
91
  if worker_pools
89
92
  setup_pools
90
93
  elsif @options[:identifier]
94
+ # rubocop:disable GuardClause
91
95
  if worker_count > 1
92
96
  raise ArgumentError, 'Cannot specify both --number-of-workers and --identifier'
93
97
  else
94
98
  run_process("delayed_job.#{@options[:identifier]}", @options)
95
99
  end
100
+ # rubocop:enable GuardClause
96
101
  else
97
102
  worker_count.times do |worker_index|
98
103
  process_name = worker_count == 1 ? 'delayed_job' : "delayed_job.#{worker_index}"
@@ -8,5 +8,5 @@ module Delayed
8
8
  end
9
9
  end
10
10
 
11
- class FatalBackendError < Exception; end
11
+ class FatalBackendError < RuntimeError; end
12
12
  end
@@ -1,5 +1,5 @@
1
1
  module Delayed
2
- class InvalidCallback < Exception; end
2
+ class InvalidCallback < RuntimeError; end
3
3
 
4
4
  class Lifecycle
5
5
  EVENTS = {
@@ -6,9 +6,11 @@ module Delayed
6
6
  @options = options
7
7
  end
8
8
 
9
+ # rubocop:disable MethodMissing
9
10
  def method_missing(method, *args)
10
11
  Job.enqueue({:payload_object => @payload_class.new(@target, method.to_sym, args)}.merge(@options))
11
12
  end
13
+ # rubocop:enable MethodMissing
12
14
  end
13
15
 
14
16
  module MessageSending
@@ -26,36 +28,36 @@ module Delayed
26
28
  warn '[DEPRECATION] `object.send_at(time, :method)` is deprecated. Use `object.delay(:run_at => time).method'
27
29
  __delay__(:run_at => time).__send__(method, *args)
28
30
  end
31
+ end
29
32
 
30
- module ClassMethods
31
- def handle_asynchronously(method, opts = {}) # rubocop:disable PerceivedComplexity
32
- aliased_method = method.to_s.sub(/([?!=])$/, '')
33
- punctuation = $1 # rubocop:disable PerlBackrefs
34
- with_method = "#{aliased_method}_with_delay#{punctuation}"
35
- without_method = "#{aliased_method}_without_delay#{punctuation}"
36
- define_method(with_method) do |*args|
37
- curr_opts = opts.clone
38
- curr_opts.each_key do |key|
39
- next unless (val = curr_opts[key]).is_a?(Proc)
40
- curr_opts[key] = if val.arity == 1
41
- val.call(self)
42
- else
43
- val.call
44
- end
33
+ module MessageSendingClassMethods
34
+ def handle_asynchronously(method, opts = {}) # rubocop:disable PerceivedComplexity
35
+ aliased_method = method.to_s.sub(/([?!=])$/, '')
36
+ punctuation = $1 # rubocop:disable PerlBackrefs
37
+ with_method = "#{aliased_method}_with_delay#{punctuation}"
38
+ without_method = "#{aliased_method}_without_delay#{punctuation}"
39
+ define_method(with_method) do |*args|
40
+ curr_opts = opts.clone
41
+ curr_opts.each_key do |key|
42
+ next unless (val = curr_opts[key]).is_a?(Proc)
43
+ curr_opts[key] = if val.arity == 1
44
+ val.call(self)
45
+ else
46
+ val.call
45
47
  end
46
- delay(curr_opts).__send__(without_method, *args)
47
48
  end
49
+ delay(curr_opts).__send__(without_method, *args)
50
+ end
48
51
 
49
- alias_method without_method, method
50
- alias_method method, with_method
52
+ alias_method without_method, method
53
+ alias_method method, with_method
51
54
 
52
- if public_method_defined?(without_method)
53
- public method
54
- elsif protected_method_defined?(without_method)
55
- protected method
56
- elsif private_method_defined?(without_method)
57
- private method
58
- end
55
+ if public_method_defined?(without_method)
56
+ public method
57
+ elsif protected_method_defined?(without_method)
58
+ protected method
59
+ elsif private_method_defined?(without_method)
60
+ private method
59
61
  end
60
62
  end
61
63
  end
@@ -30,9 +30,11 @@ module Delayed
30
30
  object.method(sym)
31
31
  end
32
32
 
33
+ # rubocop:disable MethodMissing
33
34
  def method_missing(symbol, *args)
34
35
  object.send(symbol, *args)
35
36
  end
37
+ # rubocop:enable MethodMissing
36
38
 
37
39
  def respond_to?(symbol, include_private = false)
38
40
  super || object.respond_to?(symbol, include_private)
@@ -37,7 +37,7 @@ module Delayed
37
37
  klass = result.class
38
38
  id = result[klass.primary_key]
39
39
  begin
40
- klass.find(id)
40
+ klass.unscoped.find(id)
41
41
  rescue ActiveRecord::RecordNotFound => error # rubocop:disable BlockNesting
42
42
  raise Delayed::DeserializationError, "ActiveRecord::RecordNotFound, class: #{klass}, primary key: #{id} (#{error.message})"
43
43
  end
@@ -233,6 +233,8 @@ module Delayed
233
233
  job_say job, format('COMPLETED after %.4f', runtime)
234
234
  return true # did work
235
235
  rescue DeserializationError => error
236
+ job_say job, "FAILED permanently with #{error.class.name}: #{error.message}", 'error'
237
+
236
238
  job.error = error
237
239
  failed(job)
238
240
  rescue Exception => error # rubocop:disable RescueException
@@ -268,7 +270,7 @@ module Delayed
268
270
  end
269
271
 
270
272
  def job_say(job, text, level = default_log_level)
271
- text = "Job #{job.name} (id=#{job.id}) #{text}"
273
+ text = "Job #{job.name} (id=#{job.id})#{say_queue(job.queue)} #{text}"
272
274
  say text, level
273
275
  end
274
276
 
@@ -293,6 +295,10 @@ module Delayed
293
295
 
294
296
  protected
295
297
 
298
+ def say_queue(queue)
299
+ " (queue=#{queue})" if queue
300
+ end
301
+
296
302
  def handle_failed_job(job, error)
297
303
  job.error = error
298
304
  job_say job, "FAILED (#{job.attempts} prior attempts) with #{error.class.name}: #{error.message}", 'error'
@@ -320,8 +326,12 @@ module Delayed
320
326
 
321
327
  def reload!
322
328
  return unless self.class.reload_app?
323
- ActionDispatch::Reloader.cleanup!
324
- ActionDispatch::Reloader.prepare!
329
+ if defined?(ActiveSupport::Reloader)
330
+ Rails.application.reloader.reload!
331
+ else
332
+ ActionDispatch::Reloader.cleanup!
333
+ ActionDispatch::Reloader.prepare!
334
+ end
325
335
  end
326
336
  end
327
337
  end
@@ -1,3 +1,4 @@
1
+ require 'active_support'
1
2
  require 'delayed/compatibility'
2
3
  require 'delayed/exceptions'
3
4
  require 'delayed/message_sending'
@@ -19,4 +20,4 @@ require 'delayed/deserialization_error'
19
20
  require 'delayed/railtie' if defined?(Rails::Railtie)
20
21
 
21
22
  Object.send(:include, Delayed::MessageSending)
22
- Module.send(:include, Delayed::MessageSending::ClassMethods)
23
+ Module.send(:include, Delayed::MessageSendingClassMethods)
@@ -6,6 +6,6 @@ class DelayedJobGenerator < Rails::Generators::Base
6
6
 
7
7
  def create_executable_file
8
8
  template 'script', "#{Delayed::Compatibility.executable_prefix}/delayed_job"
9
- chmod "#{Delayed::Compatibility.executable_prefix}/delayed_job", 0755
9
+ chmod "#{Delayed::Compatibility.executable_prefix}/delayed_job", 0o755
10
10
  end
11
11
  end
@@ -1,7 +1,6 @@
1
1
  # Make sure this file does not get required manually
2
2
  module Autoloaded
3
3
  class Clazz
4
- def perform
5
- end
4
+ def perform; end
6
5
  end
7
6
  end
@@ -1,6 +1,5 @@
1
1
  module Autoloaded
2
2
  class InstanceClazz
3
- def perform
4
- end
3
+ def perform; end
5
4
  end
6
5
  end
@@ -1,7 +1,6 @@
1
1
  module Autoloaded
2
2
  InstanceStruct = ::Struct.new(nil)
3
3
  class InstanceStruct
4
- def perform
5
- end
4
+ def perform; end
6
5
  end
7
6
  end
@@ -2,7 +2,6 @@
2
2
  module Autoloaded
3
3
  Struct = ::Struct.new(nil)
4
4
  class Struct
5
- def perform
6
- end
5
+ def perform; end
7
6
  end
8
7
  end
@@ -1,6 +1,11 @@
1
1
  require 'helper'
2
2
 
3
3
  describe Delayed::MessageSending do
4
+ it 'does not include ClassMethods along with MessageSending' do
5
+ expect { ClassMethods }.to raise_error(NameError)
6
+ expect(defined?(String::ClassMethods)).to eq(nil)
7
+ end
8
+
4
9
  describe 'handle_asynchronously' do
5
10
  class Story
6
11
  def tell!(_arg); end
@@ -19,7 +24,7 @@ describe Delayed::MessageSending do
19
24
  expect(job.payload_object.class).to eq(Delayed::PerformableMethod)
20
25
  expect(job.payload_object.method_name).to eq(:tell_without_delay!)
21
26
  expect(job.payload_object.args).to eq([1])
22
- end.to change { Delayed::Job.count }
27
+ end.to(change { Delayed::Job.count })
23
28
  end
24
29
 
25
30
  describe 'with options' do
@@ -42,8 +47,7 @@ describe Delayed::MessageSending do
42
47
  describe 'using a proc with parameters' do
43
48
  class Yarn
44
49
  attr_accessor :importance
45
- def spin
46
- end
50
+ def spin; end
47
51
  handle_asynchronously :spin, :priority => proc { |y| y.importance }
48
52
  end
49
53
 
@@ -107,7 +111,7 @@ describe Delayed::MessageSending do
107
111
  expect do
108
112
  fairy_tail.delay.tell
109
113
  end.to change(fairy_tail, :happy_ending).from(nil).to(true)
110
- end.not_to change { Delayed::Job.count }
114
+ end.not_to(change { Delayed::Job.count })
111
115
  end
112
116
 
113
117
  it 'does delay the job when delay_jobs is true' do
@@ -137,7 +141,7 @@ describe Delayed::MessageSending do
137
141
  expect do
138
142
  fairy_tail.delay.tell
139
143
  end.to change(fairy_tail, :happy_ending).from(nil).to(true)
140
- end.not_to change { Delayed::Job.count }
144
+ end.not_to(change { Delayed::Job.count })
141
145
  end
142
146
  end
143
147
  end
@@ -30,8 +30,7 @@ describe Delayed::PerformableMethod do
30
30
 
31
31
  it 'does not raise NoMethodError if target method is private' do
32
32
  clazz = Class.new do
33
- def private_method
34
- end
33
+ def private_method; end
35
34
  private :private_method
36
35
  end
37
36
  expect { Delayed::PerformableMethod.new(clazz.new, :private_method, []) }.not_to raise_error
@@ -24,15 +24,23 @@ describe Delayed::Worker do
24
24
  describe 'job_say' do
25
25
  before do
26
26
  @worker = Delayed::Worker.new
27
- @job = double('job', :id => 123, :name => 'ExampleJob')
27
+ @job = double('job', :id => 123, :name => 'ExampleJob', :queue => nil)
28
28
  end
29
29
 
30
30
  it 'logs with job name and id' do
31
+ expect(@job).to receive(:queue)
31
32
  expect(@worker).to receive(:say).
32
33
  with('Job ExampleJob (id=123) message', Delayed::Worker.default_log_level)
33
34
  @worker.job_say(@job, 'message')
34
35
  end
35
36
 
37
+ it 'logs with job name, queue and id' do
38
+ expect(@job).to receive(:queue).and_return('test')
39
+ expect(@worker).to receive(:say).
40
+ with('Job ExampleJob (id=123) (queue=test) message', Delayed::Worker.default_log_level)
41
+ @worker.job_say(@job, 'message')
42
+ end
43
+
36
44
  it 'has a configurable default log level' do
37
45
  Delayed::Worker.default_log_level = 'error'
38
46
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.1.2
4
+ version: 4.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brandon Keepers
@@ -15,7 +15,7 @@ authors:
15
15
  autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
- date: 2016-05-16 00:00:00.000000000 Z
18
+ date: 2017-05-26 00:00:00.000000000 Z
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
21
21
  name: activesupport
@@ -26,7 +26,7 @@ dependencies:
26
26
  version: '3.0'
27
27
  - - "<"
28
28
  - !ruby/object:Gem::Version
29
- version: '5.1'
29
+ version: '5.2'
30
30
  type: :runtime
31
31
  prerelease: false
32
32
  version_requirements: !ruby/object:Gem::Requirement
@@ -36,7 +36,7 @@ dependencies:
36
36
  version: '3.0'
37
37
  - - "<"
38
38
  - !ruby/object:Gem::Version
39
- version: '5.1'
39
+ version: '5.2'
40
40
  description: Delayed_job (or DJ) encapsulates the common pattern of asynchronously
41
41
  executing longer tasks in the background. It is a direct extraction from Shopify
42
42
  where the job table is responsible for a multitude of core tasks.
@@ -119,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
119
119
  version: '0'
120
120
  requirements: []
121
121
  rubyforge_project:
122
- rubygems_version: 2.5.1
122
+ rubygems_version: 2.6.11
123
123
  signing_key:
124
124
  specification_version: 4
125
125
  summary: Database-backed asynchronous priority queue system -- Extracted from Shopify