delayed_job_groups_plugin 0.2.0 → 0.5.0
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 +5 -5
- data/.gitignore +1 -0
- data/.rspec +1 -0
- data/.rubocop.yml +8 -0
- data/.travis.yml +10 -20
- data/Appraisals +12 -0
- data/CHANGELOG.md +24 -1
- data/Gemfile +2 -0
- data/README.md +4 -3
- data/Rakefile +2 -0
- data/delayed_job_groups.gemspec +18 -18
- data/gemfiles/rails_5.2.gemfile +9 -0
- data/gemfiles/rails_6.0.gemfile +8 -0
- data/lib/delayed/job_groups/compatibility.rb +2 -2
- data/lib/delayed/job_groups/job_extensions.rb +7 -8
- data/lib/delayed/job_groups/job_group.rb +9 -17
- data/lib/delayed/job_groups/plugin.rb +13 -9
- data/lib/delayed/job_groups/version.rb +2 -2
- data/lib/delayed/job_groups/yaml_loader.rb +17 -0
- data/lib/delayed_job_groups_plugin.rb +2 -1
- data/lib/generators/delayed_job_groups_plugin/install_generator.rb +3 -3
- data/lib/generators/delayed_job_groups_plugin/templates/{migration.rb → migration.erb} +2 -2
- data/spec/db/schema.rb +2 -2
- data/spec/delayed/job_groups/job_group_spec.rb +22 -23
- data/spec/delayed/job_groups/plugin_spec.rb +133 -84
- data/spec/delayed/job_groups/yaml_loader_spec.rb +43 -0
- data/spec/spec_helper.rb +12 -12
- data/spec/support/destroyed_model.rb +3 -3
- metadata +83 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e66577a1ef061e5623346875c94024af0dccf4f15f3788d86c9fab410b5a3620
|
4
|
+
data.tar.gz: 4353a8d9b1bcbe29c256367e5ad3502cdd93ebd2a351e90a1c706294661dfd28
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b872e26617a67db33ca43d8da7bb24ebfaa253a1c110aff02204c7d64f54b4852cf98b6804cefabfb2dba700fdab6f9eda5fe6edd2881490ec26fe59a42fb111
|
7
|
+
data.tar.gz: 16154ad9d50605537785e50dda77f1500bb67fff8035d2c41e311956ff34b312d44749904f6d606436698ddbaae0858816a27a5c690e5fd5d756e8bf4cd17e54
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
data/.rubocop.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,22 +1,12 @@
|
|
1
1
|
language: ruby
|
2
|
-
|
3
|
-
|
4
|
-
-
|
5
|
-
-
|
6
|
-
- RAILS_VERSION="~> 4.2.0" JRUBY_OPTS="$JRUBY_OPTS --debug"
|
2
|
+
sudo: false
|
3
|
+
gemfile:
|
4
|
+
- gemfiles/rails_5.2.gemfile
|
5
|
+
- gemfiles/rails_6.0.gemfile
|
7
6
|
rvm:
|
8
|
-
-
|
9
|
-
- 2.
|
10
|
-
- 2.
|
11
|
-
|
12
|
-
-
|
13
|
-
|
14
|
-
exclude:
|
15
|
-
# See https://github.com/salsify/goldiloader/issues/22
|
16
|
-
- rvm: jruby-19mode
|
17
|
-
env: RAILS_VERSION="~> 4.2.0" JRUBY_OPTS="$JRUBY_OPTS --debug"
|
18
|
-
# See https://github.com/rails/rails/pull/18306
|
19
|
-
- rvm: 2.2.0
|
20
|
-
env: RAILS_VERSION="~> 3.2.21" JRUBY_OPTS="$JRUBY_OPTS --debug"
|
21
|
-
before_install:
|
22
|
-
- gem install bundler
|
7
|
+
- 2.5.8
|
8
|
+
- 2.6.6
|
9
|
+
- 2.7.2
|
10
|
+
script:
|
11
|
+
- bundle exec rspec
|
12
|
+
- bundle exec rubocop
|
data/Appraisals
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,28 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
### 0.5.0
|
4
|
+
* Drop support for Ruby 2.3 and 2.4.
|
5
|
+
* Drop support for Rails < 5.2.
|
6
|
+
* Bugfix for rails version in generated migration files
|
7
|
+
|
8
|
+
### 0.4.3
|
9
|
+
* Bugfix for `on_completion_job` when `failure_cancels_group` is set to false.
|
10
|
+
|
11
|
+
### 0.4.2
|
12
|
+
* Add support for Rails 6.0.
|
13
|
+
|
14
|
+
### 0.4.1
|
15
|
+
* Bugfix for `on_completion_job` and `on_cancellation_job` YAML serialization
|
16
|
+
|
17
|
+
### 0.4.0
|
18
|
+
* Drop support for Ruby 2.0, 2.1 and 2.2.
|
19
|
+
* Add support for Ruby 2.5.
|
20
|
+
* Drop support for Rails < 4.2.
|
21
|
+
* Add support for Rails 5.2
|
22
|
+
|
23
|
+
### 0.3.0
|
24
|
+
* Drop support for Ruby 1.9 and 2.0.
|
25
|
+
|
3
26
|
### 0.2.0
|
4
27
|
* Change supported delayed job version
|
5
28
|
* Clean up lifecycle management in plugin
|
@@ -10,5 +33,5 @@
|
|
10
33
|
### 0.1.2
|
11
34
|
* Add configuration option to allow failed jobs not to cancel a group.
|
12
35
|
|
13
|
-
### 0.1.1
|
36
|
+
### 0.1.1
|
14
37
|
* Update the run_at for all jobs in a JobGroup when it's unblocked.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -100,15 +100,16 @@ job_group.cancel
|
|
100
100
|
|
101
101
|
Configuration to allow failed jobs not to cancel the group
|
102
102
|
```ruby
|
103
|
-
# We can optionally pass options that will allow jobs to fail without cancelling the group
|
103
|
+
# We can optionally pass options that will allow jobs to fail without cancelling the group.
|
104
|
+
# This also allows the on_completion job to fire once all jobs have either succeeded or failed.
|
104
105
|
job_group = Delayed::JobGroups::JobGroup.create!(failure_cancels_group: false)
|
105
106
|
```
|
106
107
|
|
107
108
|
## Supported Platforms
|
108
109
|
|
109
110
|
* Only the Delayed Job Active Record backend is supported.
|
110
|
-
* Tested with Rails
|
111
|
-
* Tested with MRI
|
111
|
+
* Tested with Rails 4.2 through 5.2.
|
112
|
+
* Tested with MRI 2.3 through 2.5.
|
112
113
|
|
113
114
|
## Contributing
|
114
115
|
|
data/Rakefile
CHANGED
data/delayed_job_groups.gemspec
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
2
4
|
lib = File.expand_path('../lib', __FILE__)
|
3
5
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
6
|
require 'delayed/job_groups/version'
|
@@ -8,34 +10,32 @@ Gem::Specification.new do |spec|
|
|
8
10
|
spec.version = Delayed::JobGroups::VERSION
|
9
11
|
spec.authors = ['Joel Turkel', 'Randy Burkes']
|
10
12
|
spec.email = ['jturkel@salsify.com', 'rlburkes@gmail.com']
|
11
|
-
spec.description =
|
12
|
-
spec.summary =
|
13
|
+
spec.description = 'Aggregates Delayed::Job jobs into groups with group level management and lifecycle callbacks'
|
14
|
+
spec.summary = 'Delayed::Job job groups plugin'
|
13
15
|
spec.homepage = 'https://github.com/salsify/delayed_job_groups_plugin'
|
14
16
|
spec.license = 'MIT'
|
15
17
|
|
16
|
-
spec.files = `git ls-files`.split(
|
18
|
+
spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
17
19
|
spec.test_files = Dir.glob('spec/**/*')
|
18
20
|
spec.require_paths = ['lib']
|
19
21
|
|
22
|
+
spec.required_ruby_version = '>= 2.5'
|
23
|
+
|
20
24
|
spec.add_dependency 'delayed_job', '>= 4.1'
|
21
|
-
spec.add_dependency 'delayed_job_active_record', '>=
|
25
|
+
spec.add_dependency 'delayed_job_active_record', '>= 4.1'
|
22
26
|
|
23
27
|
spec.post_install_message = 'See https://github.com/salsify/delayed_job_groups_plugin#installation for upgrade/installation notes.'
|
24
28
|
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.
|
29
|
+
spec.add_development_dependency 'appraisal'
|
30
|
+
spec.add_dependency 'activerecord', '>= 5.2', '< 6.1'
|
31
|
+
spec.add_development_dependency 'coveralls_reborn', '>= 0.18.0'
|
27
32
|
spec.add_development_dependency 'database_cleaner', '>= 1.2'
|
33
|
+
spec.add_development_dependency 'mime-types'
|
28
34
|
spec.add_development_dependency 'rake'
|
29
|
-
spec.add_development_dependency 'rspec', '
|
30
|
-
spec.add_development_dependency '
|
35
|
+
spec.add_development_dependency 'rspec', '~> 3'
|
36
|
+
spec.add_development_dependency 'rspec-its'
|
37
|
+
spec.add_development_dependency 'salsify_rubocop', '0.52.1.1'
|
38
|
+
spec.add_development_dependency 'simplecov'
|
39
|
+
spec.add_development_dependency 'sqlite3'
|
31
40
|
spec.add_development_dependency 'timecop'
|
32
|
-
spec.add_development_dependency 'mime-types', '~> 2'
|
33
|
-
|
34
|
-
if RUBY_PLATFORM == 'java'
|
35
|
-
spec.add_development_dependency 'jdbc-sqlite3'
|
36
|
-
spec.add_development_dependency 'activerecord-jdbcsqlite3-adapter'
|
37
|
-
else
|
38
|
-
spec.add_development_dependency 'sqlite3'
|
39
|
-
end
|
40
|
-
|
41
41
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/version'
|
4
4
|
require 'active_record/version'
|
@@ -8,7 +8,7 @@ module Delayed
|
|
8
8
|
module Compatibility
|
9
9
|
|
10
10
|
def self.mass_assignment_security_enabled?
|
11
|
-
|
11
|
+
defined?(::ActiveRecord::MassAssignmentSecurity)
|
12
12
|
end
|
13
13
|
|
14
14
|
end
|
@@ -1,9 +1,14 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Delayed
|
4
4
|
module JobGroups
|
5
5
|
module JobExtensions
|
6
6
|
extend ActiveSupport::Concern
|
7
|
+
module ReadyToRunExtension
|
8
|
+
def ready_to_run(worker_name, max_run_time)
|
9
|
+
super(worker_name, max_run_time).where(blocked: false)
|
10
|
+
end
|
11
|
+
end
|
7
12
|
|
8
13
|
included do
|
9
14
|
if Delayed::JobGroups::Compatibility.mass_assignment_security_enabled?
|
@@ -13,15 +18,9 @@ module Delayed
|
|
13
18
|
belongs_to :job_group, class_name: 'Delayed::JobGroups::JobGroup'
|
14
19
|
|
15
20
|
class << self
|
16
|
-
|
17
|
-
# Patch ready_to_run to exclude blocked jobs
|
18
|
-
def ready_to_run_with_blocked_filtering(worker_name, max_run_time)
|
19
|
-
ready_to_run_without_blocked_filtering(worker_name, max_run_time).where(blocked: false)
|
20
|
-
end
|
21
|
-
alias_method_chain :ready_to_run, :blocked_filtering
|
21
|
+
prepend ReadyToRunExtension
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
25
24
|
def in_job_group?
|
26
25
|
job_group_id.present?
|
27
26
|
end
|
@@ -1,4 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'yaml_loader'
|
2
4
|
|
3
5
|
module Delayed
|
4
6
|
module JobGroups
|
@@ -11,29 +13,19 @@ module Delayed
|
|
11
13
|
:on_cancellation_job_options, :failure_cancels_group
|
12
14
|
end
|
13
15
|
|
14
|
-
serialize :on_completion_job
|
16
|
+
serialize :on_completion_job, Delayed::JobGroups::YamlLoader
|
15
17
|
serialize :on_completion_job_options, Hash
|
16
|
-
serialize :on_cancellation_job
|
18
|
+
serialize :on_cancellation_job, Delayed::JobGroups::YamlLoader
|
17
19
|
serialize :on_cancellation_job_options, Hash
|
18
20
|
|
19
21
|
validates :queueing_complete, :blocked, :failure_cancels_group, inclusion: [true, false]
|
20
22
|
|
21
|
-
|
22
|
-
has_many :active_jobs, -> { where(failed_at: nil) }, class_name: Job
|
23
|
-
else
|
24
|
-
has_many :active_jobs, class_name: Job, conditions: {failed_at: nil}
|
25
|
-
end
|
26
|
-
|
23
|
+
has_many :active_jobs, -> { where(failed_at: nil) }, class_name: '::Delayed::Job'
|
27
24
|
|
28
25
|
# Only delete dependent jobs that are unlocked so we can determine if there are in-flight jobs
|
29
26
|
# for canceled job groups
|
30
|
-
|
31
|
-
|
32
|
-
dependent: :delete_all
|
33
|
-
else
|
34
|
-
has_many :queued_jobs, class_name: Job, conditions: {failed_at: nil, locked_by: nil},
|
35
|
-
dependent: :delete_all
|
36
|
-
end
|
27
|
+
has_many :queued_jobs, -> { where(failed_at: nil, locked_by: nil) }, class_name: '::Delayed::Job',
|
28
|
+
dependent: :delete_all
|
37
29
|
|
38
30
|
def mark_queueing_complete
|
39
31
|
with_lock do
|
@@ -78,7 +70,7 @@ module Delayed
|
|
78
70
|
end
|
79
71
|
end
|
80
72
|
|
81
|
-
def self.has_pending_jobs?(job_group_ids)
|
73
|
+
def self.has_pending_jobs?(job_group_ids) # rubocop:disable Naming/PredicateName
|
82
74
|
job_group_ids = Array(job_group_ids)
|
83
75
|
return false if job_group_ids.empty?
|
84
76
|
Delayed::Job.where(job_group_id: job_group_ids, failed_at: nil).exists?
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'delayed_job'
|
4
4
|
require 'set'
|
@@ -8,7 +8,7 @@ module Delayed
|
|
8
8
|
class Plugin < Delayed::Plugin
|
9
9
|
|
10
10
|
callbacks do |lifecycle|
|
11
|
-
lifecycle.before(:error) do |
|
11
|
+
lifecycle.before(:error) do |_worker, job|
|
12
12
|
# If the job group has been cancelled then don't let the job be retried
|
13
13
|
if job.in_job_group? && job_group_cancelled?(job.job_group_id)
|
14
14
|
def job.max_attempts
|
@@ -17,7 +17,7 @@ module Delayed
|
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
|
-
lifecycle.before(:failure) do |
|
20
|
+
lifecycle.before(:failure) do |_worker, job|
|
21
21
|
# If a job in the job group fails, then cancel the whole job group.
|
22
22
|
# Need to check that the job group is present since another
|
23
23
|
# job may have concurrently cancelled it.
|
@@ -26,17 +26,16 @@ module Delayed
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
lifecycle.after(:perform) do |
|
29
|
+
lifecycle.after(:perform) do |_worker, job|
|
30
30
|
# Make sure we only check to see if the job group is complete
|
31
|
-
# if the job succeeded
|
32
|
-
|
31
|
+
# if the job succeeded or the job has failed (maxed out retries) with failure_cancels_group
|
32
|
+
# set to false
|
33
|
+
if job.in_job_group? && (job_completed?(job) || job_acceptably_failed?(job))
|
33
34
|
JobGroup.check_for_completion(job.job_group_id)
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
37
38
|
|
38
|
-
private
|
39
|
-
|
40
39
|
def self.job_group_cancelled?(job_group_id)
|
41
40
|
!JobGroup.exists?(job_group_id)
|
42
41
|
end
|
@@ -46,7 +45,12 @@ module Delayed
|
|
46
45
|
# if it has completed
|
47
46
|
job.destroyed?
|
48
47
|
end
|
48
|
+
|
49
|
+
def self.job_acceptably_failed?(job)
|
50
|
+
# Job has set failed_at (retries have maxed out) and failure_cancels_group is false signaling
|
51
|
+
# that the group should complete despite failures.
|
52
|
+
job.failed_at.present? && job.job_group.present? && !job.job_group.failure_cancels_group?
|
53
|
+
end
|
49
54
|
end
|
50
55
|
end
|
51
56
|
end
|
52
|
-
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Delayed
|
4
|
+
module JobGroups
|
5
|
+
module YamlLoader
|
6
|
+
def self.load(yaml)
|
7
|
+
return yaml unless yaml.is_a?(String) && /^---/.match(yaml)
|
8
|
+
YAML.load_dj(yaml)
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.dump(object)
|
12
|
+
return if object.nil?
|
13
|
+
YAML.dump(object)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support'
|
4
4
|
require 'active_record'
|
@@ -8,6 +8,7 @@ require 'delayed/job_groups/compatibility'
|
|
8
8
|
require 'delayed/job_groups/job_extensions'
|
9
9
|
require 'delayed/job_groups/job_group'
|
10
10
|
require 'delayed/job_groups/plugin'
|
11
|
+
require 'delayed/job_groups/yaml_loader'
|
11
12
|
require 'delayed/job_groups/version'
|
12
13
|
|
13
14
|
Delayed::Backend::ActiveRecord::Job.send(:include, Delayed::JobGroups::JobExtensions)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'rails/generators'
|
4
4
|
require 'rails/generators/migration'
|
@@ -8,10 +8,10 @@ module DelayedJobGroupsPlugin
|
|
8
8
|
class InstallGenerator < Rails::Generators::Base
|
9
9
|
include Rails::Generators::Migration
|
10
10
|
|
11
|
-
|
11
|
+
source_paths << File.join(File.dirname(__FILE__), 'templates')
|
12
12
|
|
13
13
|
def create_migration_file
|
14
|
-
migration_template('migration.
|
14
|
+
migration_template('migration.erb', 'db/migrate/create_delayed_job_groups.rb')
|
15
15
|
end
|
16
16
|
|
17
17
|
def self.next_migration_number(dirname)
|