delayed_job_groups_plugin 0.7.0 → 0.9.0

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
  SHA256:
3
- metadata.gz: d9fb6a8ff3bc2cada4bb9a8f76382ca323eed8539188646efccd80a1b767acac
4
- data.tar.gz: 90e5ea6437fc1485d8ca26a34062e3a30de989c7f8d8751643280d3830d12c79
3
+ metadata.gz: 392054f5714a429eb7c2ebdde98483c314ce2cfb75730b245b09b50e7a985b14
4
+ data.tar.gz: c91fa4ec6ad52ec7df474b66206d2d6e8f2a605236d9a9172ff7eefe0566a84f
5
5
  SHA512:
6
- metadata.gz: 943569571301edf9a43a3a73c967fb165fb5fcda2e9576a3d0ace3b2a5a3bf2a4fe46e73cc812d0498ec09b2bf2fa8ffc56bee70741f5e29d30aa4ca653ce822
7
- data.tar.gz: 0f26bbf975f3d5c727aa639afe5ea1e974fd0c8623031e62fbec78467237c8b44ea31d28f977c8dd74fb15779f8cd951a530504a9e24181ae69579ccde29a7a8
6
+ metadata.gz: 18a9acd69ea9789c1633289b2b39cc5fa8a497276eb574397b307294d890aedb90ac8d9537077c36fe28547abf3c514eb8881408a1fda093270c73f5ac80b7f7
7
+ data.tar.gz: 0f3d59781205003bc9aa0c50d6a1e34cea7d23a5d5318928187858bb5ed6e64cb3159b659955691016b7b1de4ca345b2bcbaa574ec9bcae06e9d97061208b900
data/.circleci/config.yml CHANGED
@@ -2,14 +2,14 @@ version: 2.1
2
2
  jobs:
3
3
  lint:
4
4
  docker:
5
- - image: salsify/ruby_ci:2.6.6
5
+ - image: cimg/ruby:3.0.6
6
6
  working_directory: ~/delayed_job_groups
7
7
  steps:
8
8
  - checkout
9
9
  - restore_cache:
10
10
  keys:
11
- - v1-gems-ruby-2.6.6-{{ checksum "delayed_job_groups.gemspec" }}-{{ checksum "Gemfile" }}
12
- - v1-gems-ruby-2.6.6-
11
+ - v1-gems-ruby-3.0.6-{{ checksum "delayed_job_groups.gemspec" }}-{{ checksum "Gemfile" }}
12
+ - v1-gems-ruby-3.0.6-
13
13
  - run:
14
14
  name: Install Gems
15
15
  command: |
@@ -18,7 +18,7 @@ jobs:
18
18
  bundle clean
19
19
  fi
20
20
  - save_cache:
21
- key: v1-gems-ruby-2.6.6-{{ checksum "delayed_job_groups.gemspec" }}-{{ checksum "Gemfile" }}
21
+ key: v1-gems-ruby-3.0.6-{{ checksum "delayed_job_groups.gemspec" }}-{{ checksum "Gemfile" }}
22
22
  paths:
23
23
  - "vendor/bundle"
24
24
  - "gemfiles/vendor/bundle"
@@ -32,7 +32,7 @@ jobs:
32
32
  ruby_version:
33
33
  type: string
34
34
  docker:
35
- - image: salsify/ruby_ci:<< parameters.ruby_version >>
35
+ - image: cimg/ruby:<< parameters.ruby_version >>
36
36
  environment:
37
37
  CIRCLE_TEST_REPORTS: "test-results"
38
38
  BUNDLE_GEMFILE: << parameters.gemfile >>
@@ -69,13 +69,9 @@ workflows:
69
69
  matrix:
70
70
  parameters:
71
71
  gemfile:
72
- - "gemfiles/rails_5.2.gemfile"
73
- - "gemfiles/rails_6.0.gemfile"
74
72
  - "gemfiles/rails_6.1.gemfile"
73
+ - "gemfiles/rails_7.0.gemfile"
75
74
  ruby_version:
76
- - "2.6.6"
77
- - "2.7.2"
78
- - "3.0.0"
79
- exclude:
80
- - gemfile: "gemfiles/rails_5.2.gemfile"
81
- ruby_version: "3.0.0"
75
+ - "3.0.6"
76
+ - "3.1.4"
77
+ - "3.2.2"
@@ -0,0 +1 @@
1
+ * @jturkel @salsify/infrastructure-services
data/.gitignore CHANGED
@@ -19,3 +19,4 @@ test/tmp
19
19
  test/version_tmp
20
20
  tmp
21
21
  *.gemfile.lock
22
+ .ruby-version
data/.rubocop.yml CHANGED
@@ -2,7 +2,7 @@ inherit_gem:
2
2
  salsify_rubocop: conf/rubocop.yml
3
3
 
4
4
  AllCops:
5
- TargetRubyVersion: 2.6
5
+ TargetRubyVersion: 3.0
6
6
  Exclude:
7
7
  - 'vendor/**/*'
8
8
  - 'gemfiles/**/*'
data/Appraisals CHANGED
@@ -1,17 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'rails-5.2' do
4
- gem 'sqlite3', '~> 1.3.6'
5
- gem 'activerecord', '5.2.1'
6
- gem 'activesupport', '5.2.1'
7
- end
8
-
9
- appraise 'rails-6.0' do
10
- gem 'activerecord', '6.0.3'
11
- gem 'activesupport', '6.0.3'
3
+ appraise 'rails-6.1' do
4
+ gem 'activerecord', '~> 6.1.5'
5
+ gem 'activesupport', '~> 6.1.5'
12
6
  end
13
7
 
14
- appraise 'rails-6.1' do
15
- gem 'activerecord', '6.1.0'
16
- gem 'activesupport', '6.1.0'
8
+ appraise 'rails-7.0' do
9
+ gem 'activerecord', '~> 7.0.2'
10
+ gem 'activesupport', '~> 7.0.2'
17
11
  end
data/CHANGELOG.md CHANGED
@@ -1,4 +1,16 @@
1
1
  # Changelog
2
+
3
+ ### 0.9.0
4
+ - Add a `CompleteStuckJobGroupsJob`, which can be run periodically to close "stuck" job groups
5
+ - Drop support for Ruby 2.7
6
+ - Drop support for Rails 6.0
7
+
8
+ ### 0.8.0
9
+ - Drop support for ruby < 2.7
10
+ - Add support for ruby 3.1
11
+ - Drop Rails 5.2
12
+ - Add Rails 7.0
13
+
2
14
  ### 0.7.0
3
15
  * Add support for ruby 3
4
16
  * Drop support for ruby < 2.6
data/README.md CHANGED
@@ -49,7 +49,7 @@ Creating a job group and queueing some jobs:
49
49
  ```ruby
50
50
  job_group = Delayed::JobGroups::JobGroup.create!
51
51
 
52
- # JobGroup#enqueue has the same signature as Delayed::Job.enqueue
52
+ # JobGroup#enqueue has the same signature as Delayed::Job.enqueue
53
53
  # i.e. it takes a job and an optional hash of options.
54
54
  job_group.enqueue(MyJob.new('some arg'), queue: 'general')
55
55
  job_group.enqueue(MyJob.new('some other arg'), queue: 'general', priority: 10)
@@ -62,7 +62,7 @@ Registering a job to run after all jobs in the job group have completed:
62
62
 
63
63
  ```ruby
64
64
  # We can optionally pass options that will be used when queueing the on completion job
65
- job_group = Delayed::JobGroups::JobGroup.create!(on_completion_job: MyCompletionJob.new,
65
+ job_group = Delayed::JobGroups::JobGroup.create!(on_completion_job: MyCompletionJob.new,
66
66
  on_completion_job_options: { queue: 'general' })
67
67
  ```
68
68
 
@@ -70,7 +70,7 @@ Registering a job to run if the job group is canceled or fails:
70
70
 
71
71
  ```ruby
72
72
  # We can optionally pass options that will be used when queueing the on cancellation job
73
- job_group = Delayed::JobGroups::JobGroup.create!(on_cancellation_job: MyCancellationJob.new,
73
+ job_group = Delayed::JobGroups::JobGroup.create!(on_cancellation_job: MyCancellationJob.new,
74
74
  on_cancellation_job_options: { queue: 'general' })
75
75
  ```
76
76
 
@@ -81,9 +81,9 @@ Block and unblock jobs in a job group:
81
81
  job_group = Delayed::JobGroups::JobGroup.create!(blocked: true)
82
82
  job_group.enqueue(MyJob.new('some arg'), queue: 'general')
83
83
  job_group.mark_queueing_complete
84
-
84
+
85
85
  # Do more stuff...
86
-
86
+
87
87
  # Unblock the JobGroup so its jobs can run
88
88
  job_group.unblock
89
89
  ```
@@ -92,19 +92,32 @@ Cancel a job group:
92
92
 
93
93
  ```ruby
94
94
  job_group = Delayed::JobGroups::JobGroup.create!
95
-
95
+
96
96
  # Do more stuff...
97
-
97
+
98
98
  job_group.cancel
99
99
  ```
100
100
 
101
101
  Configuration to allow failed jobs not to cancel the group
102
102
  ```ruby
103
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
+ # This also allows the on_completion job to fire once all jobs have either succeeded or failed.
105
105
  job_group = Delayed::JobGroups::JobGroup.create!(failure_cancels_group: false)
106
106
  ```
107
107
 
108
+ ### Maintenance
109
+
110
+ It's possible to end up in a state where all jobs in a group have been completed, but the completion job has not run.
111
+ This is due a race condition where the final job in a group is completed, and the worker running it is terminated before
112
+ the completion job can be enqueued.
113
+
114
+ As a remedy for the above scenario, a job is provided which cleans up any job groups in this state. It is recommended to
115
+ run this job periodically (for example in a cron job), especially in high-thoughput applications.
116
+
117
+ ```ruby
118
+ Delayed::JobGroups::CompleteStuckJobGroupsJob.enqueue
119
+ ```
120
+
108
121
  ## Supported Platforms
109
122
 
110
123
  * Only the Delayed Job Active Record backend is supported.
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'delayed_job_groups_plugin'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start
@@ -14,11 +14,18 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = 'https://github.com/salsify/delayed_job_groups_plugin'
15
15
  spec.license = 'MIT'
16
16
 
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
19
+ spec.metadata['rubygems_mfa_required'] = 'true'
20
+ else
21
+ raise 'RubyGems 2.0 or newer is required to set allowed_push_host.'
22
+ end
23
+
17
24
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
18
25
  spec.test_files = Dir.glob('spec/**/*')
19
26
  spec.require_paths = ['lib']
20
27
 
21
- spec.required_ruby_version = '>= 2.6'
28
+ spec.required_ruby_version = '>= 3.0'
22
29
 
23
30
  spec.add_dependency 'delayed_job', '>= 4.1'
24
31
  spec.add_dependency 'delayed_job_active_record', '>= 4.1'
@@ -27,9 +34,10 @@ Gem::Specification.new do |spec|
27
34
  'for upgrade/installation notes.'
28
35
 
29
36
  spec.add_development_dependency 'appraisal'
30
- spec.add_dependency 'activerecord', '>= 5.2', '< 7'
37
+ spec.add_dependency 'activerecord', '>= 6.1', '< 7.1'
31
38
  spec.add_development_dependency 'coveralls_reborn', '>= 0.18.0'
32
39
  spec.add_development_dependency 'database_cleaner', '>= 1.2'
40
+ spec.add_development_dependency 'factory_bot_rails'
33
41
  spec.add_development_dependency 'mime-types'
34
42
  spec.add_development_dependency 'rake'
35
43
  spec.add_development_dependency 'rspec', '~> 3'
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "6.1.0"
6
- gem "activesupport", "6.1.0"
5
+ gem "activerecord", "~> 6.1.5"
6
+ gem "activesupport", "~> 6.1.5"
7
7
 
8
8
  gemspec path: "../"
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "activerecord", "6.0.3"
6
- gem "activesupport", "6.0.3"
5
+ gem "activerecord", "~> 7.0.2"
6
+ gem "activesupport", "~> 7.0.2"
7
7
 
8
8
  gemspec path: "../"
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Delayed
4
+ module JobGroups
5
+ class CompleteStuckJobGroupsJob
6
+ class << self
7
+ def enqueue(**kwargs)
8
+ Delayed::Job.enqueue(new, **kwargs)
9
+ end
10
+ end
11
+
12
+ def perform
13
+ Delayed::JobGroups::JobGroup.ready.with_no_open_jobs.find_each do |job_group|
14
+ job_group.check_for_completion(skip_pending_jobs_check: true)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -22,6 +22,11 @@ module Delayed
22
22
  has_many :queued_jobs, -> { where(failed_at: nil, locked_by: nil) }, class_name: '::Delayed::Job',
23
23
  dependent: :delete_all
24
24
 
25
+ scope :ready, -> { where(queueing_complete: true, blocked: false) }
26
+ scope :with_no_open_jobs, -> do
27
+ where("NOT EXISTS (#{Delayed::Job.where('delayed_jobs.job_group_id = delayed_job_groups.id').to_sql})")
28
+ end
29
+
25
30
  def mark_queueing_complete
26
31
  with_lock do
27
32
  raise 'JobGroup has already completed queueing' if queueing_complete?
@@ -52,10 +57,14 @@ module Delayed
52
57
  destroy
53
58
  end
54
59
 
55
- def self.check_for_completion(job_group_id)
60
+ def check_for_completion(skip_pending_jobs_check: false)
61
+ self.class.check_for_completion(id, skip_pending_jobs_check: skip_pending_jobs_check)
62
+ end
63
+
64
+ def self.check_for_completion(job_group_id, skip_pending_jobs_check: false)
56
65
  # Optimization to avoid loading and locking the JobGroup when the group
57
66
  # still has pending jobs
58
- return if has_pending_jobs?(job_group_id)
67
+ return if !skip_pending_jobs_check && has_pending_jobs?(job_group_id)
59
68
 
60
69
  transaction do
61
70
  # The first completed job to notice the job group's queue count has dropped to
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Delayed
4
4
  module JobGroups
5
- VERSION = '0.7.0'
5
+ VERSION = '0.9.0'
6
6
  end
7
7
  end
@@ -5,6 +5,7 @@ require 'active_record'
5
5
  require 'delayed_job'
6
6
  require 'delayed_job_active_record'
7
7
  require 'delayed/job_groups/compatibility'
8
+ require 'delayed/job_groups/complete_stuck_job_groups_job'
8
9
  require 'delayed/job_groups/job_extensions'
9
10
  require 'delayed/job_groups/job_group'
10
11
  require 'delayed/job_groups/plugin'
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe Delayed::JobGroups::CompleteStuckJobGroupsJob do
4
+ describe "#perform" do
5
+ let(:job) { described_class.new }
6
+
7
+ let!(:blocked) { create(:job_group, blocked: true) }
8
+ let!(:not_queueing_complete) { create(:job_group, queueing_complete: false) }
9
+ let!(:ready_without_jobs) { create(:job_group, queueing_complete: true, blocked: false) }
10
+ let!(:ready_with_jobs) do
11
+ create(:job_group, queueing_complete: true, blocked: false).tap do |job_group|
12
+ create(:delayed_job, job_group: job_group)
13
+ end
14
+ end
15
+
16
+ before do
17
+ allow(Delayed::JobGroups::JobGroup).to receive(:check_for_completion)
18
+ end
19
+
20
+ it "checks all relevant job groups for completion" do
21
+ job.perform
22
+
23
+ expect(Delayed::JobGroups::JobGroup).to have_received(:check_for_completion)
24
+ .once
25
+ .with(ready_without_jobs.id, skip_pending_jobs_check: true)
26
+ end
27
+ end
28
+
29
+ describe "#enqueue" do
30
+ before do
31
+ allow(Delayed::Job).to receive(:enqueue)
32
+ end
33
+
34
+ it "enqueues the job" do
35
+ described_class.enqueue
36
+
37
+ expect(Delayed::Job).to have_received(:enqueue).with(instance_of(described_class))
38
+ end
39
+ end
40
+ end
@@ -2,7 +2,7 @@
2
2
 
3
3
  describe "delayed job extensions" do
4
4
  it "provides an optional job_group_id" do
5
- job_group = Delayed::JobGroups::JobGroup.create!
5
+ job_group = create(:job_group)
6
6
  expect(Delayed::Job.new(job_group_id: job_group.id)).to be_valid
7
7
  expect(Delayed::Job.new).to be_valid
8
8
  end
@@ -10,9 +10,12 @@ describe Delayed::JobGroups::JobGroup do
10
10
  let(:current_time) { Time.utc(2013) }
11
11
 
12
12
  subject(:job_group) do
13
- Delayed::JobGroups::JobGroup.create!(on_completion_job: on_completion_job,
14
- on_completion_job_options: on_completion_job_options,
15
- blocked: blocked)
13
+ create(
14
+ :job_group,
15
+ on_completion_job: on_completion_job,
16
+ on_completion_job_options: on_completion_job_options,
17
+ blocked: blocked
18
+ )
16
19
  end
17
20
 
18
21
  before do
@@ -24,6 +27,27 @@ describe Delayed::JobGroups::JobGroup do
24
27
  Timecop.return
25
28
  end
26
29
 
30
+ describe "scopes" do
31
+ describe "ready" do
32
+ let!(:blocked) { create(:job_group, blocked: true) }
33
+ let!(:not_queueing_complete) { create(:job_group, queueing_complete: false) }
34
+ let!(:ready) { create(:job_group, queueing_complete: true, blocked: false) }
35
+
36
+ it "returns the expected job groups" do
37
+ expect(described_class.ready).to match_array(ready)
38
+ end
39
+ end
40
+
41
+ describe "with_no_open_jobs" do
42
+ let!(:job_group_with_jobs) { create(:delayed_job).job_group }
43
+ let!(:job_group_without_jobs) { subject }
44
+
45
+ it "returns groups with no jobs" do
46
+ expect(described_class.with_no_open_jobs).to match_array(job_group_without_jobs)
47
+ end
48
+ end
49
+ end
50
+
27
51
  shared_examples "the job group was completed" do
28
52
  it "queues the completion job" do
29
53
  expect(Delayed::Job).to have_received(:enqueue).with(on_completion_job, on_completion_job_options)
@@ -76,7 +100,73 @@ describe Delayed::JobGroups::JobGroup do
76
100
  end
77
101
  end
78
102
 
79
- describe ".check_for_completion" do
103
+ describe "instance check_for_completion" do
104
+ let!(:job) { Delayed::Job.create!(job_group_id: job_group.id) }
105
+
106
+ before do
107
+ job_group.mark_queueing_complete
108
+ end
109
+
110
+ shared_context "complete job and check job group complete" do
111
+ before do
112
+ job.destroy!
113
+ job_group.check_for_completion
114
+ end
115
+ end
116
+
117
+ context "when no jobs exist" do
118
+ include_context "complete job and check job group complete"
119
+
120
+ it_behaves_like "the job group was completed"
121
+ end
122
+
123
+ context "when active jobs exist" do
124
+ before do
125
+ Delayed::JobGroups::JobGroup.check_for_completion(job_group.id)
126
+ end
127
+
128
+ it_behaves_like "the job group was not completed"
129
+ end
130
+
131
+ context "when on failed jobs exist" do
132
+ before do
133
+ job.update!(failed_at: Time.now)
134
+ Delayed::JobGroups::JobGroup.check_for_completion(job_group.id)
135
+ end
136
+
137
+ it_behaves_like "the job group was completed"
138
+ end
139
+
140
+ context "when there are no on_completion_job_options" do
141
+ let(:on_completion_job_options) { nil }
142
+
143
+ include_context "complete job and check job group complete"
144
+
145
+ it "queues the completion job with empty options" do
146
+ expect(Delayed::Job).to have_received(:enqueue).with(on_completion_job, {})
147
+ end
148
+
149
+ it "destroys the job group" do
150
+ expect(job_group).to have_been_destroyed
151
+ end
152
+ end
153
+
154
+ context "when there is no on_completion_job" do
155
+ let(:on_completion_job) { nil }
156
+
157
+ include_context "complete job and check job group complete"
158
+
159
+ it "doesn't queues the non-existent completion job" do
160
+ expect(Delayed::Job).not_to have_received(:enqueue)
161
+ end
162
+
163
+ it "destroys the job group" do
164
+ expect(job_group).to have_been_destroyed
165
+ end
166
+ end
167
+ end
168
+
169
+ describe "class check_for_completion" do
80
170
  let!(:job) { Delayed::Job.create!(job_group_id: job_group.id) }
81
171
 
82
172
  before do
@@ -85,7 +175,7 @@ describe Delayed::JobGroups::JobGroup do
85
175
 
86
176
  shared_context "complete job and check job group complete" do
87
177
  before do
88
- job.destroy
178
+ job.destroy!
89
179
  Delayed::JobGroups::JobGroup.check_for_completion(job_group.id)
90
180
  end
91
181
  end
@@ -13,7 +13,7 @@ describe Delayed::JobGroups::Plugin do
13
13
  Delayed::Worker.max_attempts = @old_max_attempts
14
14
  end
15
15
 
16
- let!(:job_group) { Delayed::JobGroups::JobGroup.create!(on_completion_job: TestJobs::CompletionJob.new) }
16
+ let!(:job_group) { create(:job_group, on_completion_job: TestJobs::CompletionJob.new) }
17
17
 
18
18
  it "runs the completion job after completing other jobs" do
19
19
  job_group.enqueue(TestJobs::NoOpJob.new)
@@ -215,8 +215,11 @@ describe Delayed::JobGroups::Plugin do
215
215
 
216
216
  context "when a cancellation job is provided" do
217
217
  let!(:job_group) do
218
- Delayed::JobGroups::JobGroup.create!(on_completion_job: TestJobs::CompletionJob.new,
219
- on_cancellation_job: TestJobs::CancellationJob.new)
218
+ create(
219
+ :job_group,
220
+ on_completion_job: TestJobs::CompletionJob.new,
221
+ on_cancellation_job: TestJobs::CancellationJob.new
222
+ )
220
223
  end
221
224
 
222
225
  it "runs the cancellation job after a job error causes cancellation" do
@@ -262,7 +265,7 @@ describe Delayed::JobGroups::Plugin do
262
265
  end
263
266
 
264
267
  context "when a no completion job is provided" do
265
- let!(:job_group) { Delayed::JobGroups::JobGroup.create! }
268
+ let!(:job_group) { create(:job_group) }
266
269
 
267
270
  it "doesn't queue a non-existent completion job" do
268
271
  job_group.enqueue(TestJobs::NoOpJob.new)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :delayed_job, class: 'Delayed::Job' do
5
+ job_group { create(:job_group) }
6
+ end
7
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ FactoryBot.define do
4
+ factory :job_group, class: 'Delayed::JobGroups::JobGroup' do
5
+ blocked { false }
6
+ queueing_complete { false }
7
+ on_completion_job { nil }
8
+ on_completion_job_options { nil }
9
+ end
10
+ end
data/spec/spec_helper.rb CHANGED
@@ -14,6 +14,7 @@ end
14
14
  require 'rspec/its'
15
15
  require 'database_cleaner'
16
16
  require 'delayed_job_groups_plugin'
17
+ require 'factory_bot'
17
18
  require 'yaml'
18
19
  require 'timecop'
19
20
 
@@ -40,6 +41,7 @@ RSpec.configure do |config|
40
41
 
41
42
  config.before(:suite) do
42
43
  DatabaseCleaner.clean_with(:truncation)
44
+ FactoryBot.find_definitions
43
45
  end
44
46
 
45
47
  config.before do
@@ -53,4 +55,6 @@ RSpec.configure do |config|
53
55
  config.after do
54
56
  DatabaseCleaner.clean
55
57
  end
58
+
59
+ config.include FactoryBot::Syntax::Methods
56
60
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job_groups_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Turkel
8
8
  - Randy Burkes
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-02-22 00:00:00.000000000 Z
12
+ date: 2023-09-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: delayed_job
@@ -59,20 +59,20 @@ dependencies:
59
59
  requirements:
60
60
  - - ">="
61
61
  - !ruby/object:Gem::Version
62
- version: '5.2'
62
+ version: '6.1'
63
63
  - - "<"
64
64
  - !ruby/object:Gem::Version
65
- version: '7'
65
+ version: '7.1'
66
66
  type: :runtime
67
67
  prerelease: false
68
68
  version_requirements: !ruby/object:Gem::Requirement
69
69
  requirements:
70
70
  - - ">="
71
71
  - !ruby/object:Gem::Version
72
- version: '5.2'
72
+ version: '6.1'
73
73
  - - "<"
74
74
  - !ruby/object:Gem::Version
75
- version: '7'
75
+ version: '7.1'
76
76
  - !ruby/object:Gem::Dependency
77
77
  name: coveralls_reborn
78
78
  requirement: !ruby/object:Gem::Requirement
@@ -101,6 +101,20 @@ dependencies:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
103
  version: '1.2'
104
+ - !ruby/object:Gem::Dependency
105
+ name: factory_bot_rails
106
+ requirement: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ type: :development
112
+ prerelease: false
113
+ version_requirements: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
104
118
  - !ruby/object:Gem::Dependency
105
119
  name: mime-types
106
120
  requirement: !ruby/object:Gem::Requirement
@@ -237,6 +251,7 @@ extensions: []
237
251
  extra_rdoc_files: []
238
252
  files:
239
253
  - ".circleci/config.yml"
254
+ - ".github/CODEOWNERS"
240
255
  - ".gitignore"
241
256
  - ".rspec"
242
257
  - ".rubocop.yml"
@@ -246,11 +261,12 @@ files:
246
261
  - LICENSE.txt
247
262
  - README.md
248
263
  - Rakefile
264
+ - bin/console
249
265
  - delayed_job_groups.gemspec
250
- - gemfiles/rails_5.2.gemfile
251
- - gemfiles/rails_6.0.gemfile
252
266
  - gemfiles/rails_6.1.gemfile
267
+ - gemfiles/rails_7.0.gemfile
253
268
  - lib/delayed/job_groups/compatibility.rb
269
+ - lib/delayed/job_groups/complete_stuck_job_groups_job.rb
254
270
  - lib/delayed/job_groups/job_extensions.rb
255
271
  - lib/delayed/job_groups/job_group.rb
256
272
  - lib/delayed/job_groups/plugin.rb
@@ -262,17 +278,22 @@ files:
262
278
  - lib/generators/delayed_job_groups_plugin/templates/migration.erb
263
279
  - spec/db/database.yml
264
280
  - spec/db/schema.rb
281
+ - spec/delayed/job_groups/complete_stuck_job_groups_job_spec.rb
265
282
  - spec/delayed/job_groups/job_extensions_spec.rb
266
283
  - spec/delayed/job_groups/job_group_spec.rb
267
284
  - spec/delayed/job_groups/plugin_spec.rb
268
285
  - spec/delayed/job_groups/yaml_loader_spec.rb
286
+ - spec/factories/delayed_jobs.rb
287
+ - spec/factories/job_groups.rb
269
288
  - spec/spec_helper.rb
270
289
  - spec/support/destroyed_model.rb
271
290
  - spec/support/test_jobs.rb
272
291
  homepage: https://github.com/salsify/delayed_job_groups_plugin
273
292
  licenses:
274
293
  - MIT
275
- metadata: {}
294
+ metadata:
295
+ allowed_push_host: https://rubygems.org
296
+ rubygems_mfa_required: 'true'
276
297
  post_install_message: See https://github.com/salsify/delayed_job_groups_plugin#installation
277
298
  for upgrade/installation notes.
278
299
  rdoc_options: []
@@ -282,24 +303,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
282
303
  requirements:
283
304
  - - ">="
284
305
  - !ruby/object:Gem::Version
285
- version: '2.6'
306
+ version: '3.0'
286
307
  required_rubygems_version: !ruby/object:Gem::Requirement
287
308
  requirements:
288
309
  - - ">="
289
310
  - !ruby/object:Gem::Version
290
311
  version: '0'
291
312
  requirements: []
292
- rubygems_version: 3.1.4
293
- signing_key:
313
+ rubygems_version: 3.3.26
314
+ signing_key:
294
315
  specification_version: 4
295
316
  summary: Delayed::Job job groups plugin
296
317
  test_files:
318
+ - spec/db/database.yml
319
+ - spec/db/schema.rb
320
+ - spec/delayed/job_groups/complete_stuck_job_groups_job_spec.rb
321
+ - spec/delayed/job_groups/job_extensions_spec.rb
322
+ - spec/delayed/job_groups/job_group_spec.rb
323
+ - spec/delayed/job_groups/plugin_spec.rb
324
+ - spec/delayed/job_groups/yaml_loader_spec.rb
325
+ - spec/factories/delayed_jobs.rb
326
+ - spec/factories/job_groups.rb
297
327
  - spec/spec_helper.rb
298
328
  - spec/support/destroyed_model.rb
299
329
  - spec/support/test_jobs.rb
300
- - spec/delayed/job_groups/plugin_spec.rb
301
- - spec/delayed/job_groups/job_group_spec.rb
302
- - spec/delayed/job_groups/yaml_loader_spec.rb
303
- - spec/delayed/job_groups/job_extensions_spec.rb
304
- - spec/db/schema.rb
305
- - spec/db/database.yml
@@ -1,9 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "sqlite3", "~> 1.3.6"
6
- gem "activerecord", "5.2.1"
7
- gem "activesupport", "5.2.1"
8
-
9
- gemspec path: "../"