delayed_job 4.1.1 → 4.1.2

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: 226d8094c23242fff24504c004ec32a007561ec2
4
- data.tar.gz: 57c4fcad04cbb3202e310b7cac10a5c476d4817b
3
+ metadata.gz: 4f13f44eb18f5903178447ab50ddd453895632b3
4
+ data.tar.gz: 20c22a692ca3d8084a85fdb3e401f209d822eb3b
5
5
  SHA512:
6
- metadata.gz: 967992dc5cdff3bce673aae3de9c442cd7387d3dc5d09c3c6d5ffad4c14714e134687baf6cdcd9408b962d45da1d37418fba91ea6b943263cc98969e744f6ebd
7
- data.tar.gz: a713c81fad5e6454edafeb65455b7233f74fef09e420e0c5359394d8e640aee75c295c232e4ac4c5b23b5d9876b58dca7c3b9495589dc074776b8d228b5650a0
6
+ metadata.gz: a2d9edf1e02e8fd824a5016a7761e049b0b3ae90509231d021858475dbfa7fe5695cf3a150b4564fe998e0d6fa11e39bde9017c0022ae899452a46f52d192c58
7
+ data.tar.gz: a0a6875d0e951fbd0a3f442e2b699605bb36074b4c38ececaec501b721717ea64800fa191ed1ebae1b528ba7e8f7d8caee1c53115dc741870e7dc034ed916211
@@ -1,3 +1,9 @@
1
+ 4.1.2 - 2016-05-16
2
+ * Added Delayed::Worker.queue_attributes
3
+ * Limit what we require in ActiveSupport
4
+ * Fix pid file creation when there is no tmp directory
5
+ * Rails 5 support
6
+
1
7
  4.1.1 - 2015-09-24
2
8
  ==================
3
9
  * Fix shared specs for back-ends that reload objects
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.0.6).](https://github.com/collectiveidea/delayed_job/tree/v4.0.6)**
4
+ (4.1.2).](https://github.com/collectiveidea/delayed_job/tree/v4.1.2)**
5
5
 
6
6
  Delayed::Job
7
7
  ============
@@ -205,6 +205,21 @@ Delayed::Job.enqueue job, :queue => 'tracking'
205
205
  handle_asynchronously :tweet_later, :queue => 'tweets'
206
206
  ```
207
207
 
208
+ You can configure default priorities for named queues:
209
+
210
+ ```ruby
211
+ Delayed::Worker.queue_attributes = {
212
+ high_priority: { priority: -10 },
213
+ low_priority: { priority: 10 }
214
+ }
215
+ ```
216
+
217
+ Configured queue priorities can be overriden by passing priority to the delay method
218
+
219
+ ```ruby
220
+ object.delay(:queue => 'high_priority', priority: 0).method
221
+ ```
222
+
208
223
  Running Jobs
209
224
  ============
210
225
  `script/delayed_job` can be used to manage a background process which will
@@ -425,6 +440,8 @@ The default behavior is to read 5 jobs from the queue when finding an available
425
440
 
426
441
  By default all jobs will be queued without a named queue. A default named queue can be specified by using `Delayed::Worker.default_queue_name`.
427
442
 
443
+ If no jobs are found, the worker sleeps for the amount of time specified by the sleep delay option. Set `Delayed::Worker.sleep_delay = 60` for a 60 second sleep time.
444
+
428
445
  It is possible to disable delayed jobs for testing purposes. Set `Delayed::Worker.delay_jobs = false` to execute all jobs realtime.
429
446
 
430
447
  Or `Delayed::Worker.delay_jobs` can be a Proc that decides whether to execute jobs inline on a per-job basis:
@@ -1,15 +1,17 @@
1
+ # -*- encoding: utf-8 -*-
2
+
1
3
  Gem::Specification.new do |spec|
2
- spec.add_dependency 'activesupport', ['>= 3.0', '< 5.0']
4
+ spec.add_dependency 'activesupport', ['>= 3.0', '< 5.1']
3
5
  spec.authors = ['Brandon Keepers', 'Brian Ryckbost', 'Chris Gaffney', 'David Genord II', 'Erik Michaels-Ober', 'Matt Griffin', 'Steve Richert', 'Tobias Lütke']
4
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.'
5
7
  spec.email = ['brian@collectiveidea.com']
6
8
  spec.files = %w[CHANGELOG.md CONTRIBUTING.md LICENSE.md README.md Rakefile delayed_job.gemspec]
7
- spec.files += Dir.glob('{contrib,lib,recipes,spec}/**/*')
9
+ spec.files += Dir.glob('{contrib,lib,recipes,spec}/**/*') # rubocop:disable SpaceAroundOperators
8
10
  spec.homepage = 'http://github.com/collectiveidea/delayed_job'
9
11
  spec.licenses = ['MIT']
10
12
  spec.name = 'delayed_job'
11
13
  spec.require_paths = ['lib']
12
14
  spec.summary = 'Database-backed asynchronous priority queue system -- Extracted from Shopify'
13
15
  spec.test_files = Dir.glob('spec/**/*')
14
- spec.version = '4.1.1'
16
+ spec.version = '4.1.2'
15
17
  end
@@ -7,28 +7,12 @@ module Delayed
7
7
 
8
8
  module ClassMethods
9
9
  # Add a job to the queue
10
- def enqueue(*args) # rubocop:disable CyclomaticComplexity
11
- options = args.extract_options!
12
- options[:payload_object] ||= args.shift
13
- options[:priority] ||= Delayed::Worker.default_priority
14
-
15
- if options[:queue].nil?
16
- if options[:payload_object].respond_to?(:queue_name)
17
- options[:queue] = options[:payload_object].queue_name
18
- end
19
- options[:queue] ||= Delayed::Worker.default_queue_name
20
- end
21
-
22
- if args.size > 0
23
- warn '[DEPRECATION] Passing multiple arguments to `#enqueue` is deprecated. Pass a hash with :priority and :run_at.'
24
- options[:priority] = args.first || options[:priority]
25
- options[:run_at] = args[1]
26
- end
27
-
28
- unless options[:payload_object].respond_to?(:perform)
29
- raise ArgumentError, 'Cannot enqueue items which do not respond to perform'
30
- end
10
+ def enqueue(*args)
11
+ job_options = Delayed::Backend::JobPreparer.new(*args).prepare
12
+ enqueue_job(job_options)
13
+ end
31
14
 
15
+ def enqueue_job(options)
32
16
  new(options).tap do |job|
33
17
  Delayed::Worker.lifecycle.run_callbacks(:enqueue, job) do
34
18
  job.hook(:enqueue)
@@ -66,7 +50,7 @@ module Delayed
66
50
  attr_reader :error
67
51
  def error=(error)
68
52
  @error = error
69
- self.last_error = "#{error.message}\n#{error.backtrace.join("\n")}" if self.respond_to?(:last_error=)
53
+ self.last_error = "#{error.message}\n#{error.backtrace.join("\n")}" if respond_to?(:last_error=)
70
54
  end
71
55
 
72
56
  def failed?
@@ -74,7 +58,7 @@ module Delayed
74
58
  end
75
59
  alias_method :failed, :failed?
76
60
 
77
- ParseObjectFromYaml = /\!ruby\/\w+\:([^\s]+)/ # rubocop:disable ConstantName
61
+ ParseObjectFromYaml = %r{\!ruby/\w+\:([^\s]+)} # rubocop:disable ConstantName
78
62
 
79
63
  def name
80
64
  @name ||= payload_object.respond_to?(:display_name) ? payload_object.display_name : payload_object.class.name
@@ -0,0 +1,51 @@
1
+ module Delayed
2
+ module Backend
3
+ class JobPreparer
4
+ attr_reader :options, :args
5
+
6
+ def initialize(*args)
7
+ @options = args.extract_options!
8
+ @args = args
9
+ end
10
+
11
+ def prepare
12
+ set_payload
13
+ set_queue_name
14
+ set_priority
15
+ handle_deprecation
16
+ options
17
+ end
18
+
19
+ private
20
+
21
+ def set_payload
22
+ options[:payload_object] ||= args.shift
23
+ end
24
+
25
+ def set_queue_name
26
+ if options[:queue].nil? && options[:payload_object].respond_to?(:queue_name)
27
+ options[:queue] = options[:payload_object].queue_name
28
+ else
29
+ options[:queue] ||= Delayed::Worker.default_queue_name
30
+ end
31
+ end
32
+
33
+ def set_priority
34
+ queue_attribute = Delayed::Worker.queue_attributes[options[:queue]]
35
+ options[:priority] ||= (queue_attribute && queue_attribute[:priority]) || Delayed::Worker.default_priority
36
+ end
37
+
38
+ def handle_deprecation
39
+ if args.size > 0
40
+ warn '[DEPRECATION] Passing multiple arguments to `#enqueue` is deprecated. Pass a hash with :priority and :run_at.'
41
+ options[:priority] = args.first || options[:priority]
42
+ options[:run_at] = args[1]
43
+ end
44
+
45
+ unless options[:payload_object].respond_to?(:perform)
46
+ raise ArgumentError, 'Cannot enqueue items which do not respond to perform'
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../../../../spec/sample_jobs', __FILE__)
2
2
 
3
- require 'active_support/core_ext'
3
+ require 'active_support/core_ext/numeric/time'
4
4
 
5
5
  shared_examples_for 'a delayed_job backend' do
6
6
  let(:worker) { Delayed::Worker.new }
@@ -279,6 +279,7 @@ shared_examples_for 'a delayed_job backend' do
279
279
  after do
280
280
  Delayed::Worker.max_priority = nil
281
281
  Delayed::Worker.min_priority = nil
282
+ Delayed::Worker.queue_attributes = {}
282
283
  end
283
284
 
284
285
  it 'fetches jobs ordered by priority' do
@@ -314,6 +315,18 @@ shared_examples_for 'a delayed_job backend' do
314
315
  end
315
316
  expect(described_class.reserve(worker)).to be_nil
316
317
  end
318
+
319
+ it 'sets job priority based on queue_attributes configuration' do
320
+ Delayed::Worker.queue_attributes = {'job_tracking' => {:priority => 4}}
321
+ job = described_class.enqueue :payload_object => NamedQueueJob.new
322
+ expect(job.priority).to eq(4)
323
+ end
324
+
325
+ it 'sets job priority based on the passed in priority overrideing queue_attributes configuration' do
326
+ Delayed::Worker.queue_attributes = {'job_tracking' => {:priority => 4}}
327
+ job = described_class.enqueue :payload_object => NamedQueueJob.new, :priority => 10
328
+ expect(job.priority).to eq(10)
329
+ end
317
330
  end
318
331
 
319
332
  context 'clear_locks!' do
@@ -5,6 +5,7 @@ unless ENV['RAILS_ENV'] == 'test'
5
5
  raise "You need to add gem 'daemons' to your Gemfile if you wish to use it."
6
6
  end
7
7
  end
8
+ require 'fileutils'
8
9
  require 'optparse'
9
10
  require 'pathname'
10
11
 
@@ -32,7 +33,7 @@ module Delayed
32
33
  exit 1
33
34
  end
34
35
  opt.on('-e', '--environment=NAME', 'Specifies the environment to run this delayed jobs under (test/development/production).') do |_e|
35
- STDERR.puts 'The -e/--environment option has been deprecated and has no effect. Use RAILS_ENV and see http://github.com/collectiveidea/delayed_job/issues/#issue/7'
36
+ STDERR.puts 'The -e/--environment option has been deprecated and has no effect. Use RAILS_ENV and see http://github.com/collectiveidea/delayed_job/issues/7'
36
37
  end
37
38
  opt.on('--min-priority N', 'Minimum priority of jobs to run.') do |n|
38
39
  @options[:min_priority] = n
@@ -82,7 +83,7 @@ module Delayed
82
83
 
83
84
  def daemonize # rubocop:disable PerceivedComplexity
84
85
  dir = @options[:pid_dir]
85
- Dir.mkdir(dir) unless File.exist?(dir)
86
+ FileUtils.mkdir_p(dir) unless File.exist?(dir)
86
87
 
87
88
  if worker_pools
88
89
  setup_pools
@@ -142,11 +143,7 @@ module Delayed
142
143
  @worker_pools ||= []
143
144
 
144
145
  queues, worker_count = pool.split(':')
145
- if ['*', '', nil].include?(queues)
146
- queues = []
147
- else
148
- queues = queues.split(',')
149
- end
146
+ queues = ['*', '', nil].include?(queues) ? [] : queues.split(',')
150
147
  worker_count = (worker_count || 1).to_i rescue 1
151
148
  @worker_pools << [queues, worker_count]
152
149
  end
@@ -10,7 +10,7 @@ module Delayed
10
10
  :error => [:worker, :job],
11
11
  :failure => [:worker, :job],
12
12
  :invoke_job => [:job]
13
- }
13
+ }.freeze
14
14
 
15
15
  def initialize
16
16
  @callbacks = EVENTS.keys.each_with_object({}) do |e, hash|
@@ -1,5 +1,3 @@
1
- require 'active_support/core_ext/module/aliasing'
2
-
3
1
  module Delayed
4
2
  class DelayProxy < Delayed::Compatibility.proxy_object_class
5
3
  def initialize(payload_class, target, options)
@@ -30,7 +28,7 @@ module Delayed
30
28
  end
31
29
 
32
30
  module ClassMethods
33
- def handle_asynchronously(method, opts = {})
31
+ def handle_asynchronously(method, opts = {}) # rubocop:disable PerceivedComplexity
34
32
  aliased_method = method.to_s.sub(/([?!=])$/, '')
35
33
  punctuation = $1 # rubocop:disable PerlBackrefs
36
34
  with_method = "#{aliased_method}_with_delay#{punctuation}"
@@ -47,7 +45,17 @@ module Delayed
47
45
  end
48
46
  delay(curr_opts).__send__(without_method, *args)
49
47
  end
50
- alias_method_chain method, :delay
48
+
49
+ alias_method without_method, method
50
+ alias_method method, with_method
51
+
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
51
59
  end
52
60
  end
53
61
  end
@@ -1,11 +1,7 @@
1
- require 'active_support/core_ext/module/delegation'
2
-
3
1
  module Delayed
4
2
  class PerformableMethod
5
3
  attr_accessor :object, :method_name, :args
6
4
 
7
- delegate :method, :to => :object
8
-
9
5
  def initialize(object, method_name, args)
10
6
  raise NoMethodError, "undefined method `#{method_name}' for #{object.inspect}" unless object.respond_to?(method_name, true)
11
7
 
@@ -30,6 +26,10 @@ module Delayed
30
26
  object.send(method_name, *args) if object
31
27
  end
32
28
 
29
+ def method(sym)
30
+ object.method(sym)
31
+ end
32
+
33
33
  def method_missing(symbol, *args)
34
34
  object.send(symbol, *args)
35
35
  end
@@ -31,7 +31,7 @@ module Delayed
31
31
  return revive(Psych.load_tags[object.tag], object) if Psych.load_tags[object.tag]
32
32
 
33
33
  case object.tag
34
- when /^!ruby\/object/
34
+ when %r{^!ruby/object}
35
35
  result = super
36
36
  if defined?(ActiveRecord::Base) && result.is_a?(ActiveRecord::Base)
37
37
  klass = result.class
@@ -44,7 +44,7 @@ module Delayed
44
44
  else
45
45
  result
46
46
  end
47
- when /^!ruby\/ActiveRecord:(.+)$/
47
+ when %r{^!ruby/ActiveRecord:(.+)$}
48
48
  klass = resolve_class(Regexp.last_match[1])
49
49
  payload = Hash[*object.children.map { |c| accept c }]
50
50
  id = payload['attributes'][klass.primary_key]
@@ -54,7 +54,7 @@ module Delayed
54
54
  rescue ActiveRecord::RecordNotFound => error
55
55
  raise Delayed::DeserializationError, "ActiveRecord::RecordNotFound, class: #{klass}, primary key: #{id} (#{error.message})"
56
56
  end
57
- when /^!ruby\/Mongoid:(.+)$/
57
+ when %r{^!ruby/Mongoid:(.+)$}
58
58
  klass = resolve_class(Regexp.last_match[1])
59
59
  payload = Hash[*object.children.map { |c| accept c }]
60
60
  id = payload['attributes']['_id']
@@ -63,7 +63,7 @@ module Delayed
63
63
  rescue Mongoid::Errors::DocumentNotFound => error
64
64
  raise Delayed::DeserializationError, "Mongoid::Errors::DocumentNotFound, class: #{klass}, primary key: #{id} (#{error.message})"
65
65
  end
66
- when /^!ruby\/DataMapper:(.+)$/
66
+ when %r{^!ruby/DataMapper:(.+)$}
67
67
  klass = resolve_class(Regexp.last_match[1])
68
68
  payload = Hash[*object.children.map { |c| accept c }]
69
69
  begin
@@ -1,20 +1,22 @@
1
1
  require 'timeout'
2
+ require 'active_support/dependencies'
2
3
  require 'active_support/core_ext/numeric/time'
3
4
  require 'active_support/core_ext/class/attribute_accessors'
4
- require 'active_support/core_ext/kernel'
5
- require 'active_support/core_ext/enumerable'
5
+ require 'active_support/hash_with_indifferent_access'
6
+ require 'active_support/core_ext/hash/indifferent_access'
6
7
  require 'logger'
7
8
  require 'benchmark'
8
9
 
9
10
  module Delayed
10
11
  class Worker # rubocop:disable ClassLength
11
- DEFAULT_LOG_LEVEL = 'info'
12
+ DEFAULT_LOG_LEVEL = 'info'.freeze
12
13
  DEFAULT_SLEEP_DELAY = 5
13
14
  DEFAULT_MAX_ATTEMPTS = 25
14
15
  DEFAULT_MAX_RUN_TIME = 4.hours
15
16
  DEFAULT_DEFAULT_PRIORITY = 0
16
17
  DEFAULT_DELAY_JOBS = true
17
- DEFAULT_QUEUES = []
18
+ DEFAULT_QUEUES = [].freeze
19
+ DEFAULT_QUEUE_ATTRIBUTES = HashWithIndifferentAccess.new.freeze
18
20
  DEFAULT_READ_AHEAD = 5
19
21
 
20
22
  cattr_accessor :min_priority, :max_priority, :max_attempts, :max_run_time,
@@ -25,7 +27,7 @@ module Delayed
25
27
  # Named queue into which jobs are enqueued by default
26
28
  cattr_accessor :default_queue_name
27
29
 
28
- cattr_reader :backend
30
+ cattr_reader :backend, :queue_attributes
29
31
 
30
32
  # name_prefix is ignored if name is set directly
31
33
  attr_accessor :name_prefix
@@ -38,12 +40,11 @@ module Delayed
38
40
  self.default_priority = DEFAULT_DEFAULT_PRIORITY
39
41
  self.delay_jobs = DEFAULT_DELAY_JOBS
40
42
  self.queues = DEFAULT_QUEUES
43
+ self.queue_attributes = DEFAULT_QUEUE_ATTRIBUTES
41
44
  self.read_ahead = DEFAULT_READ_AHEAD
42
45
  @lifecycle = nil
43
46
  end
44
47
 
45
- reset
46
-
47
48
  # Add or remove plugins in this list before the worker is instantiated
48
49
  self.plugins = [Delayed::Plugins::ClearLocks]
49
50
 
@@ -70,6 +71,11 @@ module Delayed
70
71
  silence_warnings { ::Delayed.const_set(:Job, backend) }
71
72
  end
72
73
 
74
+ # rubocop:disable ClassVars
75
+ def self.queue_attributes=(val)
76
+ @@queue_attributes = val.with_indifferent_access
77
+ end
78
+
73
79
  def self.guess_backend
74
80
  warn '[DEPRECATION] guess_backend is deprecated. Please remove it from your code.'
75
81
  end
@@ -170,7 +176,7 @@ module Delayed
170
176
  end
171
177
  end
172
178
 
173
- count = @result.sum
179
+ count = @result[0] + @result[1]
174
180
 
175
181
  if count.zero?
176
182
  if self.class.exit_on_complete
@@ -319,3 +325,5 @@ module Delayed
319
325
  end
320
326
  end
321
327
  end
328
+
329
+ Delayed::Worker.reset
@@ -1,4 +1,3 @@
1
- require 'active_support'
2
1
  require 'delayed/compatibility'
3
2
  require 'delayed/exceptions'
4
3
  require 'delayed/message_sending'
@@ -14,6 +13,7 @@ require 'delayed/lifecycle'
14
13
  require 'delayed/plugin'
15
14
  require 'delayed/plugins/clear_locks'
16
15
  require 'delayed/backend/base'
16
+ require 'delayed/backend/job_preparer'
17
17
  require 'delayed/worker'
18
18
  require 'delayed/deserialization_error'
19
19
  require 'delayed/railtie' if defined?(Rails::Railtie)
@@ -159,8 +159,7 @@ describe Delayed::Command do
159
159
  describe 'running worker pools defined by multiple --pool arguments' do
160
160
  it 'should run the correct worker processes' do
161
161
  command = Delayed::Command.new(['--pool=*:1', '--pool=test_queue:4', '--pool=mailers,misc:2'])
162
-
163
- expect(Dir).to receive(:mkdir).with('./tmp/pids').once
162
+ expect(FileUtils).to receive(:mkdir_p).with('./tmp/pids').once
164
163
 
165
164
  [
166
165
  ['delayed_job.0', {:quiet => true, :pid_dir => './tmp/pids', :log_dir => './log', :queues => []}],
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.1
4
+ version: 4.1.2
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: 2015-09-24 00:00:00.000000000 Z
18
+ date: 2016-05-16 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.0'
29
+ version: '5.1'
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.0'
39
+ version: '5.1'
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.
@@ -57,6 +57,7 @@ files:
57
57
  - contrib/delayed_job_rails_4_multiple.monitrc
58
58
  - delayed_job.gemspec
59
59
  - lib/delayed/backend/base.rb
60
+ - lib/delayed/backend/job_preparer.rb
60
61
  - lib/delayed/backend/shared_spec.rb
61
62
  - lib/delayed/command.rb
62
63
  - lib/delayed/compatibility.rb
@@ -118,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
118
119
  version: '0'
119
120
  requirements: []
120
121
  rubyforge_project:
121
- rubygems_version: 2.4.8
122
+ rubygems_version: 2.5.1
122
123
  signing_key:
123
124
  specification_version: 4
124
125
  summary: Database-backed asynchronous priority queue system -- Extracted from Shopify