delayed_job 4.1.2 → 4.1.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 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