delayed_job_groups_plugin 0.8.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: dc7b851a75a0814848eac3a150ddd9517411c78e8d4c5f02230bf8ed00e6dded
4
- data.tar.gz: 87d0123a70117592b305eeb1096e9c9bcf3ba590638bd522e7b453f3439db244
3
+ metadata.gz: 392054f5714a429eb7c2ebdde98483c314ce2cfb75730b245b09b50e7a985b14
4
+ data.tar.gz: c91fa4ec6ad52ec7df474b66206d2d6e8f2a605236d9a9172ff7eefe0566a84f
5
5
  SHA512:
6
- metadata.gz: caa34cca5bcc4558a85ec8147132a4596fcbe95b45b755468902a81ac89a49cc16405dd3107c6e60a6455a39d3c5b3c609a7f142e41f44220577ae0da5ace362
7
- data.tar.gz: 05d1861bf1316638dc689b59dd56a5e7ebffa6a4dfb5e2ca3a9e5fde849f4a099ce2c9927a927630a4201881f50872e4462c7e32ad221f2f006af0cd1f836375
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.7.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.7.6-{{ checksum "delayed_job_groups.gemspec" }}-{{ checksum "Gemfile" }}
12
- - v1-gems-ruby-2.7.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.7.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,10 +69,9 @@ workflows:
69
69
  matrix:
70
70
  parameters:
71
71
  gemfile:
72
- - "gemfiles/rails_6.0.gemfile"
73
72
  - "gemfiles/rails_6.1.gemfile"
74
73
  - "gemfiles/rails_7.0.gemfile"
75
74
  ruby_version:
76
- - "2.7.6"
77
- - "3.0.4"
78
- - "3.1.2"
75
+ - "3.0.6"
76
+ - "3.1.4"
77
+ - "3.2.2"
data/.github/CODEOWNERS CHANGED
@@ -1 +1 @@
1
- * @jturkel @will89
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.7
5
+ TargetRubyVersion: 3.0
6
6
  Exclude:
7
7
  - 'vendor/**/*'
8
8
  - 'gemfiles/**/*'
data/Appraisals CHANGED
@@ -1,10 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- appraise 'rails-6.0' do
4
- gem 'activerecord', '~> 6.0.4'
5
- gem 'activesupport', '~> 6.0.4'
6
- end
7
-
8
3
  appraise 'rails-6.1' do
9
4
  gem 'activerecord', '~> 6.1.5'
10
5
  gem 'activesupport', '~> 6.1.5'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
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
+
3
8
  ### 0.8.0
4
9
  - Drop support for ruby < 2.7
5
10
  - Add support for ruby 3.1
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
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.test_files = Dir.glob('spec/**/*')
26
26
  spec.require_paths = ['lib']
27
27
 
28
- spec.required_ruby_version = '>= 2.7'
28
+ spec.required_ruby_version = '>= 3.0'
29
29
 
30
30
  spec.add_dependency 'delayed_job', '>= 4.1'
31
31
  spec.add_dependency 'delayed_job_active_record', '>= 4.1'
@@ -34,9 +34,10 @@ Gem::Specification.new do |spec|
34
34
  'for upgrade/installation notes.'
35
35
 
36
36
  spec.add_development_dependency 'appraisal'
37
- spec.add_dependency 'activerecord', '>= 5.2', '< 7.1'
37
+ spec.add_dependency 'activerecord', '>= 6.1', '< 7.1'
38
38
  spec.add_development_dependency 'coveralls_reborn', '>= 0.18.0'
39
39
  spec.add_development_dependency 'database_cleaner', '>= 1.2'
40
+ spec.add_development_dependency 'factory_bot_rails'
40
41
  spec.add_development_dependency 'mime-types'
41
42
  spec.add_development_dependency 'rake'
42
43
  spec.add_development_dependency 'rspec', '~> 3'
@@ -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.8.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,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: delayed_job_groups_plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.8.0
4
+ version: 0.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Joel Turkel
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2022-04-25 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,7 +59,7 @@ 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
65
  version: '7.1'
@@ -69,7 +69,7 @@ dependencies:
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
75
  version: '7.1'
@@ -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
@@ -247,11 +261,12 @@ files:
247
261
  - LICENSE.txt
248
262
  - README.md
249
263
  - Rakefile
264
+ - bin/console
250
265
  - delayed_job_groups.gemspec
251
- - gemfiles/rails_6.0.gemfile
252
266
  - gemfiles/rails_6.1.gemfile
253
267
  - gemfiles/rails_7.0.gemfile
254
268
  - lib/delayed/job_groups/compatibility.rb
269
+ - lib/delayed/job_groups/complete_stuck_job_groups_job.rb
255
270
  - lib/delayed/job_groups/job_extensions.rb
256
271
  - lib/delayed/job_groups/job_group.rb
257
272
  - lib/delayed/job_groups/plugin.rb
@@ -263,10 +278,13 @@ files:
263
278
  - lib/generators/delayed_job_groups_plugin/templates/migration.erb
264
279
  - spec/db/database.yml
265
280
  - spec/db/schema.rb
281
+ - spec/delayed/job_groups/complete_stuck_job_groups_job_spec.rb
266
282
  - spec/delayed/job_groups/job_extensions_spec.rb
267
283
  - spec/delayed/job_groups/job_group_spec.rb
268
284
  - spec/delayed/job_groups/plugin_spec.rb
269
285
  - spec/delayed/job_groups/yaml_loader_spec.rb
286
+ - spec/factories/delayed_jobs.rb
287
+ - spec/factories/job_groups.rb
270
288
  - spec/spec_helper.rb
271
289
  - spec/support/destroyed_model.rb
272
290
  - spec/support/test_jobs.rb
@@ -285,24 +303,27 @@ required_ruby_version: !ruby/object:Gem::Requirement
285
303
  requirements:
286
304
  - - ">="
287
305
  - !ruby/object:Gem::Version
288
- version: '2.7'
306
+ version: '3.0'
289
307
  required_rubygems_version: !ruby/object:Gem::Requirement
290
308
  requirements:
291
309
  - - ">="
292
310
  - !ruby/object:Gem::Version
293
311
  version: '0'
294
312
  requirements: []
295
- rubygems_version: 3.2.33
313
+ rubygems_version: 3.3.26
296
314
  signing_key:
297
315
  specification_version: 4
298
316
  summary: Delayed::Job job groups plugin
299
317
  test_files:
300
318
  - spec/db/database.yml
301
319
  - spec/db/schema.rb
320
+ - spec/delayed/job_groups/complete_stuck_job_groups_job_spec.rb
302
321
  - spec/delayed/job_groups/job_extensions_spec.rb
303
322
  - spec/delayed/job_groups/job_group_spec.rb
304
323
  - spec/delayed/job_groups/plugin_spec.rb
305
324
  - spec/delayed/job_groups/yaml_loader_spec.rb
325
+ - spec/factories/delayed_jobs.rb
326
+ - spec/factories/job_groups.rb
306
327
  - spec/spec_helper.rb
307
328
  - spec/support/destroyed_model.rb
308
329
  - spec/support/test_jobs.rb
@@ -1,8 +0,0 @@
1
- # This file was generated by Appraisal
2
-
3
- source "https://rubygems.org"
4
-
5
- gem "activerecord", "~> 6.0.4"
6
- gem "activesupport", "~> 6.0.4"
7
-
8
- gemspec path: "../"