good_job 2.17.0 → 3.0.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 +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +45 -26
- data/app/charts/good_job/scheduled_by_queue_chart.rb +1 -1
- data/app/controllers/good_job/jobs_controller.rb +11 -11
- data/app/controllers/good_job/processes_controller.rb +1 -1
- data/app/filters/good_job/jobs_filter.rb +2 -2
- data/app/views/good_job/processes/index.html.erb +1 -9
- data/app/views/layouts/good_job/application.html.erb +1 -1
- data/lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb +9 -0
- data/lib/good_job/adapter.rb +6 -49
- data/lib/good_job/configuration.rb +4 -4
- data/lib/good_job/current_thread.rb +2 -2
- data/lib/good_job/notifier/process_registration.rb +0 -4
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +7 -8
- data/lib/models/good_job/active_job_job.rb +11 -0
- data/lib/{good_job → models/good_job}/base_record.rb +0 -0
- data/lib/{good_job → models/good_job}/cron_entry.rb +3 -3
- data/{app → lib}/models/good_job/execution.rb +3 -11
- data/{app/models/good_job/active_job_job.rb → lib/models/good_job/job.rb} +4 -4
- data/lib/{good_job → models/good_job}/lockable.rb +0 -0
- data/{app → lib}/models/good_job/process.rb +0 -9
- metadata +27 -31
- data/lib/generators/good_job/templates/update/migrations/02_add_cron_at_to_good_jobs.rb.erb +0 -14
- data/lib/generators/good_job/templates/update/migrations/03_add_cron_key_cron_at_index_to_good_jobs.rb.erb +0 -20
- data/lib/generators/good_job/templates/update/migrations/04_create_good_job_processes.rb.erb +0 -17
- data/lib/generators/good_job/templates/update/migrations/04_index_good_job_jobs_on_finished_at.rb.erb +0 -25
- data/lib/good_job/job.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a4f4e14bae83760bdeb35557a727116d053e47a9b7dbf501914606dbc45c2ef7
|
4
|
+
data.tar.gz: c06e9165b7ac5d87af0ab75291fedd0194018752f34332c1a16930ddca53e3dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 949cfcf1506ff658666113e035a875ed4ab44fa3e2c674e4d5d1440bf484d39793a1ee595ae0cb6f719136ce5541aae09a7fc2d66a049ea1bcf973b0165dc8a4
|
7
|
+
data.tar.gz: 9c9ff56251e01d60823a50f4edcea74034a36ef93929cf59adc588273da86d1e04f67c1b25d7d35efecda9309acf7f49f81d29fbc7f94249be0e3732087f9081
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,53 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v3.0.0](https://github.com/bensheldon/good_job/tree/v3.0.0) (2022-06-26)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.99.0...v3.0.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- By default, preserve job records and automatically them clean up [\#545](https://github.com/bensheldon/good_job/pull/545) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- Update tests to reflect default of `GoodJob.preserve_job_records = true`; update appraisal Gemfiles too [\#643](https://github.com/bensheldon/good_job/pull/643) ([bensheldon](https://github.com/bensheldon))
|
14
|
+
- Remove database migration shims and old migrations [\#642](https://github.com/bensheldon/good_job/pull/642) ([bensheldon](https://github.com/bensheldon))
|
15
|
+
- Remove support for EOL Rails 5.2 [\#637](https://github.com/bensheldon/good_job/pull/637) ([bensheldon](https://github.com/bensheldon))
|
16
|
+
- Remove/rename deprecated behavior and constants for GoodJob v3 [\#633](https://github.com/bensheldon/good_job/pull/633) ([bensheldon](https://github.com/bensheldon))
|
17
|
+
|
18
|
+
## [v2.99.0](https://github.com/bensheldon/good_job/tree/v2.99.0) (2022-06-26)
|
19
|
+
|
20
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.17.1...v2.99.0)
|
21
|
+
|
22
|
+
**Closed issues:**
|
23
|
+
|
24
|
+
- How to accomplish user controlled recurring jobs? [\#640](https://github.com/bensheldon/good_job/issues/640)
|
25
|
+
- "uninitialized constant GoodJob::Execution" in development env [\#634](https://github.com/bensheldon/good_job/issues/634)
|
26
|
+
|
27
|
+
**Merged pull requests:**
|
28
|
+
|
29
|
+
- Create upgrade instructions for v2.99 -\> v3.0.0 [\#641](https://github.com/bensheldon/good_job/pull/641) ([bensheldon](https://github.com/bensheldon))
|
30
|
+
- Update development dependencies; delete Gemfile.lock in CI to avoid Ruby version dependency mismatches [\#639](https://github.com/bensheldon/good_job/pull/639) ([bensheldon](https://github.com/bensheldon))
|
31
|
+
- Put more model files in `lib/models` and align specs too [\#638](https://github.com/bensheldon/good_job/pull/638) ([bensheldon](https://github.com/bensheldon))
|
32
|
+
- Generate sha256 checksums on gem release too [\#636](https://github.com/bensheldon/good_job/pull/636) ([bensheldon](https://github.com/bensheldon))
|
33
|
+
|
34
|
+
## [v2.17.1](https://github.com/bensheldon/good_job/tree/v2.17.1) (2022-06-24)
|
35
|
+
|
36
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.17.0...v2.17.1)
|
37
|
+
|
38
|
+
**Fixed bugs:**
|
39
|
+
|
40
|
+
- Move models out of `app` into `lib/models` [\#635](https://github.com/bensheldon/good_job/pull/635) ([bensheldon](https://github.com/bensheldon))
|
41
|
+
|
42
|
+
**Closed issues:**
|
43
|
+
|
44
|
+
- dashboard "delete all" does not work [\#630](https://github.com/bensheldon/good_job/issues/630)
|
45
|
+
- Concurrency controlled jobs cause infinite loops when perform\_limit is exceeded in test environments [\#609](https://github.com/bensheldon/good_job/issues/609)
|
46
|
+
|
47
|
+
**Merged pull requests:**
|
48
|
+
|
49
|
+
- Better isolate test environment: run server integration tests on port 3009 with custom pidfile; scope advisory lock counts to test database [\#632](https://github.com/bensheldon/good_job/pull/632) ([bensheldon](https://github.com/bensheldon))
|
50
|
+
|
3
51
|
## [v2.17.0](https://github.com/bensheldon/good_job/tree/v2.17.0) (2022-06-23)
|
4
52
|
|
5
53
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.16.1...v2.17.0)
|
data/README.md
CHANGED
@@ -46,6 +46,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
46
46
|
- [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs)
|
47
47
|
- [Updating](#updating)
|
48
48
|
- [Upgrading minor versions](#upgrading-minor-versions)
|
49
|
+
- [Upgrading v2 to v3](#upgrading-v2-to-v3)
|
49
50
|
- [Upgrading v1 to v2](#upgrading-v1-to-v2)
|
50
51
|
- [Go deeper](#go-deeper)
|
51
52
|
- [Exceptions, retries, and reliability](#exceptions-retries-and-reliability)
|
@@ -143,9 +144,9 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
143
144
|
|
144
145
|
## Compatibility
|
145
146
|
|
146
|
-
- **Ruby on Rails:**
|
147
|
-
- **Ruby:**
|
148
|
-
- **Postgres:**
|
147
|
+
- **Ruby on Rails:** 6.0+
|
148
|
+
- **Ruby:** Ruby 2.5+. JRuby 9.2.13+
|
149
|
+
- **Postgres:** 10.0+
|
149
150
|
|
150
151
|
## Configuration
|
151
152
|
|
@@ -279,7 +280,7 @@ Available configuration options are:
|
|
279
280
|
- `cleanup_interval_seconds` (integer) Number of seconds a Scheduler will wait before cleaning up preserved jobs. Defaults to `nil`. Can also be set with the environment variable `GOOD_JOB_CLEANUP_INTERVAL_SECONDS`.
|
280
281
|
- `inline_execution_respects_schedule` (boolean) Opt-in to future behavior of inline execution respecting scheduled jobs. Defaults to `false`.
|
281
282
|
- `logger` ([Rails Logger](https://api.rubyonrails.org/classes/ActiveSupport/Logger.html)) lets you set a custom logger for GoodJob. It should be an instance of a Rails `Logger` (Default: `Rails.logger`).
|
282
|
-
- `preserve_job_records` (boolean) keeps job records in your database even after jobs are completed. (Default: `
|
283
|
+
- `preserve_job_records` (boolean) keeps job records in your database even after jobs are completed. (Default: `true`)
|
283
284
|
- `retry_on_unhandled_error` (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Be advised this may lead to jobs being repeated infinitely ([see below for more on retries](#retries)). Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `true`)
|
284
285
|
- `on_thread_error` (proc, lambda, or callable) will be called when an Exception. It can be useful for logging errors to bug tracking services, like Sentry or Airbrake. Example:
|
285
286
|
|
@@ -310,8 +311,8 @@ Good Job’s general behavior can also be configured via attributes directly on
|
|
310
311
|
|
311
312
|
- **`GoodJob.active_record_parent_class`** (string) The ActiveRecord parent class inherited by GoodJob's ActiveRecord model `GoodJob::Job` (defaults to `"ActiveRecord::Base"`). Configure this when using [multiple databases with ActiveRecord](https://guides.rubyonrails.org/active_record_multiple_databases.html) or when other custom configuration is necessary for the ActiveRecord model to connect to the Postgres database. _The value must be a String to avoid premature initialization of ActiveRecord._
|
312
313
|
- **`GoodJob.logger`** ([Rails Logger](https://api.rubyonrails.org/classes/ActiveSupport/Logger.html)) lets you set a custom logger for GoodJob. It should be an instance of a Rails `Logger`.
|
313
|
-
- **`GoodJob.preserve_job_records`** (boolean) keeps job records in your database even after jobs are completed. (Default: `
|
314
|
-
- **`GoodJob.retry_on_unhandled_error`** (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Be advised this may lead to jobs being repeated infinitely ([see below for more on retries](#retries)). Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `
|
314
|
+
- **`GoodJob.preserve_job_records`** (boolean) keeps job records in your database even after jobs are completed. (Default: `true`)
|
315
|
+
- **`GoodJob.retry_on_unhandled_error`** (boolean) causes jobs to be re-queued and retried if they raise an instance of `StandardError`. Be advised this may lead to jobs being repeated infinitely ([see below for more on retries](#retries)). Instances of `Exception`, like SIGINT, will *always* be retried, regardless of this attribute’s value. (Default: `false`)
|
315
316
|
- **`GoodJob.on_thread_error`** (proc, lambda, or callable) will be called when an Exception. It can be useful for logging errors to bug tracking services, like Sentry or Airbrake.
|
316
317
|
|
317
318
|
You’ll generally want to configure these in `config/initializers/good_job.rb`, like so:
|
@@ -394,8 +395,6 @@ The Dashboard can be set to automatically refresh by checking "Live Poll" in the
|
|
394
395
|
|
395
396
|
GoodJob can extend ActiveJob to provide limits on concurrently running jobs, either at time of _enqueue_ or at _perform_. Limiting concurrency can help prevent duplicate, double or unecessary jobs from being enqueued, or race conditions when performing, for example when interacting with 3rd-party APIs.
|
396
397
|
|
397
|
-
**Note:** Limiting concurrency at _enqueue_ requires Rails 6.0+ because Rails 5.2 cannot halt ActiveJob callbacks.
|
398
|
-
|
399
398
|
```ruby
|
400
399
|
class MyJob < ApplicationJob
|
401
400
|
include GoodJob::ActiveJobExtensions::Concurrency
|
@@ -509,9 +508,25 @@ To perform upgrades to the GoodJob database tables:
|
|
509
508
|
1. Commit the migration files and resulting `db/schema.rb` changes.
|
510
509
|
1. Deploy the code, run the migrations against the production database, and restart server/worker processes.
|
511
510
|
|
511
|
+
#### Upgrading v2 to v3
|
512
|
+
|
513
|
+
GoodJob v3 is operationally identical to v2; upgrading to GoodJob v3 should be simple. If you are already using `>= v2.9+` no other changes are necessary.
|
514
|
+
|
515
|
+
1. Upgrade to `v2.99.x`, following the minor version upgrade process, running any remaining database migrations (`rails g good_job:update`) and addressing deprecation warnings.
|
516
|
+
1. Upgrade from `v2.99.x` to `v3.x`
|
517
|
+
|
518
|
+
Notable changes:
|
519
|
+
|
520
|
+
- Defaults to preserve job records, and automatically delete them after 14 days.
|
521
|
+
- Defaults to discarding failed jobs, instead of immediately retrying them.
|
522
|
+
- `:inline` execution mode respects job schedules. Tests can invoke `GoodJob.perform_inline` to execute jobs.
|
523
|
+
- `GoodJob::Adapter` can no longer can be initialized with custom execution options (`queues:`, `max_threads:`, `poll_interval:`).
|
524
|
+
- Renames `GoodJob::ActiveJobJob` to `GoodJob::Job`.
|
525
|
+
- Removes support for Rails 5.2.
|
526
|
+
|
512
527
|
#### Upgrading v1 to v2
|
513
528
|
|
514
|
-
GoodJob v2 introduces a new Advisory Lock key format that is different than the v1 advisory lock key format; it's therefore necessary to perform a simple, but staged production upgrade. If you are already using `>= v1.12+` no other changes are necessary.
|
529
|
+
GoodJob v2 introduces a new Advisory Lock key format that is operationally different than the v1 advisory lock key format; it's therefore necessary to perform a simple, but staged production upgrade. If you are already using `>= v1.12+` no other changes are necessary.
|
515
530
|
|
516
531
|
1. Upgrade your production environment to `v1.99.x` following the minor version upgrade process, including database migrations. `v1.99` is a transitional release that is safely compatible with both `v1.x` and `v2.0.0` because it uses both `v1`- and `v2`-formatted advisory locks.
|
517
532
|
1. Address any deprecation warnings generated by `v1.99`.
|
@@ -547,9 +562,9 @@ GoodJob.on_thread_error = -> (exception) { Raven.capture_exception(exception) }
|
|
547
562
|
|
548
563
|
#### Retries
|
549
564
|
|
550
|
-
By default, GoodJob
|
565
|
+
By default, GoodJob relies on ActiveJob's retry functionality.
|
551
566
|
|
552
|
-
|
567
|
+
ActiveJob can be configured to retry an infinite number of times, with an exponential backoff. Using ActiveJob's `retry_on` prevents exceptions from reaching GoodJob:
|
553
568
|
|
554
569
|
```ruby
|
555
570
|
class ApplicationJob < ActiveJob::Base
|
@@ -558,14 +573,7 @@ class ApplicationJob < ActiveJob::Base
|
|
558
573
|
end
|
559
574
|
```
|
560
575
|
|
561
|
-
When using `retry_on` with _a limited number of retries_, the final exception will not be rescued and will raise to GoodJob
|
562
|
-
|
563
|
-
```ruby
|
564
|
-
# config/initializers/good_job.rb
|
565
|
-
GoodJob.retry_on_unhandled_error = false
|
566
|
-
```
|
567
|
-
|
568
|
-
Alternatively, pass a block to `retry_on` to handle the final exception instead of raising it to GoodJob:
|
576
|
+
When using `retry_on` with _a limited number of retries_, the final exception will not be rescued and will raise to GoodJob's error handler. To avoid this, pass a block to `retry_on` to handle the final exception instead of raising it to GoodJob:
|
569
577
|
|
570
578
|
```ruby
|
571
579
|
class ApplicationJob < ActiveJob::Base
|
@@ -596,9 +604,11 @@ class ApplicationJob < ActiveJob::Base
|
|
596
604
|
end
|
597
605
|
```
|
598
606
|
|
607
|
+
By default, jobs will not be retried unless `retry_on` is configured. This can be overridden by setting `GoodJob.retry_on_unhandled_error` to `true`; GoodJob will then retry the failing job immediately and infinitely, potentially causing high load.
|
608
|
+
|
599
609
|
#### ActionMailer retries
|
600
610
|
|
601
|
-
Any configuration in `ApplicationJob` will have to be duplicated on `ActionMailer::MailDeliveryJob`
|
611
|
+
Any configuration in `ApplicationJob` will have to be duplicated on `ActionMailer::MailDeliveryJob` because ActionMailer uses that custom class which inherits from `ActiveJob::Base`, rather than your application's `ApplicationJob`.
|
602
612
|
|
603
613
|
You can use an initializer to configure `ActionMailer::MailDeliveryJob`, for example:
|
604
614
|
|
@@ -852,22 +862,31 @@ If your application is already using an ActiveJob backend, you will need to inst
|
|
852
862
|
|
853
863
|
GoodJob is fully instrumented with [`ActiveSupport::Notifications`](https://edgeguides.rubyonrails.org/active_support_instrumentation.html#introduction-to-instrumentation).
|
854
864
|
|
855
|
-
By default, GoodJob will
|
865
|
+
By default, GoodJob will preserve job records for 14 days after they are run, regardless of whether they succeed or not (raising a kind of `StandardError`), unless they are interrupted (raising a kind of `Exception`).
|
856
866
|
|
857
|
-
To preserve job records for later inspection, set an initializer:
|
867
|
+
To not preserve job records for later inspection, set an initializer:
|
858
868
|
|
859
869
|
```ruby
|
860
870
|
# config/initializers/good_job.rb
|
861
|
-
GoodJob.preserve_job_records = true
|
871
|
+
GoodJob.preserve_job_records = false # defaults to true, or `false` or `:on_unhandled_error`
|
872
|
+
```
|
873
|
+
|
874
|
+
GoodJob will automatically delete these job records after 14 days. The retention period, as well as the frequency GoodJob checks for deletable records can be configured:
|
875
|
+
|
876
|
+
```ruby
|
877
|
+
|
878
|
+
config.cleanup_preserved_jobs_before_seconds_ago = 14.days.to_i
|
879
|
+
config.cleanup_interval_jobs = 1_000 # Number of executed jobs between deletion sweeps.
|
880
|
+
config.cleanup_interval_seconds = 10.minutes.to_i # Number of seconds between deletion sweeps.
|
862
881
|
```
|
863
882
|
|
864
|
-
It is also
|
883
|
+
It is also possible to manually trigger a cleanup:
|
865
884
|
|
866
885
|
- For example, in a Rake task:
|
867
886
|
|
868
887
|
```ruby
|
869
|
-
GoodJob.cleanup_preserved_jobs # Will
|
870
|
-
GoodJob.cleanup_preserved_jobs(older_than: 7.days) #
|
888
|
+
GoodJob.cleanup_preserved_jobs # Will use default retention period
|
889
|
+
GoodJob.cleanup_preserved_jobs(older_than: 7.days) # custom retention period
|
871
890
|
```
|
872
891
|
|
873
892
|
- For example, using the `good_job` command-line utility:
|
@@ -9,7 +9,7 @@ module GoodJob
|
|
9
9
|
def data
|
10
10
|
end_time = Time.current
|
11
11
|
start_time = end_time - 1.day
|
12
|
-
table_name = GoodJob::
|
12
|
+
table_name = GoodJob::Job.table_name
|
13
13
|
|
14
14
|
count_query = Arel.sql(GoodJob::Execution.pg_or_jdbc_query(<<~SQL.squish))
|
15
15
|
SELECT *
|
@@ -10,8 +10,8 @@ module GoodJob
|
|
10
10
|
destroy: "destroyed",
|
11
11
|
}.freeze
|
12
12
|
|
13
|
-
rescue_from GoodJob::
|
14
|
-
GoodJob::
|
13
|
+
rescue_from GoodJob::Job::AdapterNotGoodJobError,
|
14
|
+
GoodJob::Job::ActionForStateMismatchError,
|
15
15
|
with: :redirect_on_error
|
16
16
|
|
17
17
|
def index
|
@@ -26,7 +26,7 @@ module GoodJob
|
|
26
26
|
JobsFilter.new(params).filtered_query
|
27
27
|
else
|
28
28
|
job_ids = params.fetch(:job_ids, [])
|
29
|
-
|
29
|
+
Job.where(active_job_id: job_ids)
|
30
30
|
end
|
31
31
|
|
32
32
|
processed_jobs = jobs.map do |job|
|
@@ -42,7 +42,7 @@ module GoodJob
|
|
42
42
|
end
|
43
43
|
|
44
44
|
job
|
45
|
-
rescue GoodJob::
|
45
|
+
rescue GoodJob::Job::ActionForStateMismatchError
|
46
46
|
nil
|
47
47
|
end.compact
|
48
48
|
|
@@ -56,29 +56,29 @@ module GoodJob
|
|
56
56
|
end
|
57
57
|
|
58
58
|
def show
|
59
|
-
@job =
|
59
|
+
@job = Job.find(params[:id])
|
60
60
|
end
|
61
61
|
|
62
62
|
def discard
|
63
|
-
@job =
|
63
|
+
@job = Job.find(params[:id])
|
64
64
|
@job.discard_job(DISCARD_MESSAGE)
|
65
65
|
redirect_back(fallback_location: jobs_path, notice: "Job has been discarded")
|
66
66
|
end
|
67
67
|
|
68
68
|
def reschedule
|
69
|
-
@job =
|
69
|
+
@job = Job.find(params[:id])
|
70
70
|
@job.reschedule_job
|
71
71
|
redirect_back(fallback_location: jobs_path, notice: "Job has been rescheduled")
|
72
72
|
end
|
73
73
|
|
74
74
|
def retry
|
75
|
-
@job =
|
75
|
+
@job = Job.find(params[:id])
|
76
76
|
@job.retry_job
|
77
77
|
redirect_back(fallback_location: jobs_path, notice: "Job has been retried")
|
78
78
|
end
|
79
79
|
|
80
80
|
def destroy
|
81
|
-
@job =
|
81
|
+
@job = Job.find(params[:id])
|
82
82
|
@job.destroy_job
|
83
83
|
redirect_back(fallback_location: jobs_path, notice: "Job has been destroyed")
|
84
84
|
end
|
@@ -87,9 +87,9 @@ module GoodJob
|
|
87
87
|
|
88
88
|
def redirect_on_error(exception)
|
89
89
|
alert = case exception
|
90
|
-
when GoodJob::
|
90
|
+
when GoodJob::Job::AdapterNotGoodJobError
|
91
91
|
"ActiveJob Queue Adapter must be GoodJob."
|
92
|
-
when GoodJob::
|
92
|
+
when GoodJob::Job::ActionForStateMismatchError
|
93
93
|
"Job is not in an appropriate state for this action."
|
94
94
|
else
|
95
95
|
exception.to_s
|
@@ -31,7 +31,7 @@ module GoodJob
|
|
31
31
|
when 'scheduled'
|
32
32
|
query = query.scheduled
|
33
33
|
when 'running'
|
34
|
-
query = query.running.select("#{GoodJob::
|
34
|
+
query = query.running.select("#{GoodJob::Job.table_name}.*", 'pg_locks.locktype')
|
35
35
|
when 'queued'
|
36
36
|
query = query.queued
|
37
37
|
end
|
@@ -47,7 +47,7 @@ module GoodJob
|
|
47
47
|
private
|
48
48
|
|
49
49
|
def default_base_query
|
50
|
-
GoodJob::
|
50
|
+
GoodJob::Job.all
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -3,15 +3,7 @@
|
|
3
3
|
</div>
|
4
4
|
|
5
5
|
<div data-live-poll-region="processes">
|
6
|
-
<% if
|
7
|
-
<div class="card my-3">
|
8
|
-
<div class="card-body">
|
9
|
-
<p class="card-text">
|
10
|
-
<em>Feature unavailable because of pending database migration.</em>
|
11
|
-
</p>
|
12
|
-
</div>
|
13
|
-
</div>
|
14
|
-
<% elsif @processes.present? %>
|
6
|
+
<% if @processes.present? %>
|
15
7
|
<div class="card my-3">
|
16
8
|
<div class="table-responsive">
|
17
9
|
<table class="table card-table table-bordered table-hover table-sm mb-0">
|
@@ -16,7 +16,7 @@
|
|
16
16
|
<%= tag.script "", src: rails_ujs_path(format: :js, v: GoodJob::VERSION, locale: nil), nonce: content_security_policy_nonce %>
|
17
17
|
|
18
18
|
<%= tag.script "", src: es_module_shims_path(format: :js, v: GoodJob::VERSION, locale: nil), async: true, nonce: content_security_policy_nonce %>
|
19
|
-
<% importmaps = { imports: GoodJob::AssetsController.js_modules.keys.
|
19
|
+
<% importmaps = { imports: GoodJob::AssetsController.js_modules.keys.index_with { |module_name| modules_path(module_name, format: :js, locale: nil, v: GoodJob::VERSION) } } %>
|
20
20
|
<%= tag.script importmaps.to_json.html_safe, type: "importmap", nonce: content_security_policy_nonce %>
|
21
21
|
<%= tag.script "", src: scripts_path(format: :js, v: GoodJob::VERSION, locale: nil), type: "module", nonce: content_security_policy_nonce %>
|
22
22
|
</head>
|
@@ -18,6 +18,12 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
18
18
|
t.text :concurrency_key
|
19
19
|
t.text :cron_key
|
20
20
|
t.uuid :retried_good_job_id
|
21
|
+
t.timestamp :cron_at
|
22
|
+
end
|
23
|
+
|
24
|
+
create_table :good_job_processes, id: :uuid do |t|
|
25
|
+
t.timestamps
|
26
|
+
t.jsonb :state
|
21
27
|
end
|
22
28
|
|
23
29
|
add_index :good_jobs, :scheduled_at, where: "(finished_at IS NULL)", name: "index_good_jobs_on_scheduled_at"
|
@@ -25,5 +31,8 @@ class CreateGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
|
25
31
|
add_index :good_jobs, [:active_job_id, :created_at], name: :index_good_jobs_on_active_job_id_and_created_at
|
26
32
|
add_index :good_jobs, :concurrency_key, where: "(finished_at IS NULL)", name: :index_good_jobs_on_concurrency_key_when_unfinished
|
27
33
|
add_index :good_jobs, [:cron_key, :created_at], name: :index_good_jobs_on_cron_key_and_created_at
|
34
|
+
add_index :good_jobs, [:cron_key, :cron_at], name: :index_good_jobs_on_cron_key_and_cron_at, unique: true
|
35
|
+
add_index :good_jobs, [:active_job_id], name: :index_good_jobs_on_active_job_id
|
36
|
+
add_index :good_jobs, [:finished_at], where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL", name: :index_good_jobs_jobs_on_finished_at
|
28
37
|
end
|
29
38
|
end
|
data/lib/good_job/adapter.rb
CHANGED
@@ -20,32 +20,16 @@ module GoodJob
|
|
20
20
|
#
|
21
21
|
# The default value depends on the Rails environment:
|
22
22
|
#
|
23
|
-
# - +development
|
23
|
+
# - +development+: +:async:+
|
24
|
+
# -+test+: +:inline+
|
24
25
|
# - +production+ and all other environments: +:external+
|
25
26
|
#
|
26
|
-
|
27
|
-
|
28
|
-
# @param poll_interval [Integer, nil] sets the number of seconds between polls for jobs when +execution_mode+ is set to +:async+. You can also set this with the environment variable +GOOD_JOB_POLL_INTERVAL+. Defaults to +1+.
|
29
|
-
# @param start_async_on_initialize [Boolean] whether to start the async scheduler when the adapter is initialized.
|
30
|
-
def initialize(execution_mode: nil, queues: nil, max_threads: nil, poll_interval: nil, start_async_on_initialize: nil)
|
31
|
-
if queues || max_threads || poll_interval || start_async_on_initialize
|
32
|
-
ActiveSupport::Deprecation.warn(
|
33
|
-
"GoodJob::Adapter's execution-related arguments (queues, max_threads, poll_interval, start_async_on_initialize) have been deprecated and will be removed in GoodJob v3. These options should be configured through GoodJob global configuration instead."
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
@configuration = GoodJob::Configuration.new(
|
38
|
-
{
|
39
|
-
execution_mode: execution_mode,
|
40
|
-
queues: queues,
|
41
|
-
max_threads: max_threads,
|
42
|
-
poll_interval: poll_interval,
|
43
|
-
}
|
44
|
-
)
|
27
|
+
def initialize(execution_mode: nil)
|
28
|
+
@configuration = GoodJob::Configuration.new({ execution_mode: execution_mode })
|
45
29
|
@configuration.validate!
|
46
30
|
self.class.instances << self
|
47
31
|
|
48
|
-
start_async if
|
32
|
+
start_async if GoodJob.async_ready?
|
49
33
|
end
|
50
34
|
|
51
35
|
# Enqueues the ActiveJob job to be performed.
|
@@ -63,11 +47,7 @@ module GoodJob
|
|
63
47
|
# @return [GoodJob::Execution]
|
64
48
|
def enqueue_at(active_job, timestamp)
|
65
49
|
scheduled_at = timestamp ? Time.zone.at(timestamp) : nil
|
66
|
-
|
67
|
-
if execute_inline?
|
68
|
-
future_scheduled = scheduled_at && scheduled_at > Time.current
|
69
|
-
will_execute_inline = !future_scheduled || (future_scheduled && !@configuration.inline_execution_respects_schedule?)
|
70
|
-
end
|
50
|
+
will_execute_inline = execute_inline? && (scheduled_at.nil? || scheduled_at <= Time.current)
|
71
51
|
|
72
52
|
execution = GoodJob::Execution.enqueue(
|
73
53
|
active_job,
|
@@ -76,29 +56,6 @@ module GoodJob
|
|
76
56
|
)
|
77
57
|
|
78
58
|
if will_execute_inline
|
79
|
-
if future_scheduled && !@configuration.inline_execution_respects_schedule?
|
80
|
-
ActiveSupport::Deprecation.warn(<<~DEPRECATION)
|
81
|
-
In the next major release, GoodJob will not *inline* execute
|
82
|
-
future-scheduled jobs.
|
83
|
-
|
84
|
-
To opt into this behavior immediately set:
|
85
|
-
`config.good_job.inline_execution_respects_schedule = true`
|
86
|
-
|
87
|
-
To perform jobs inline at any time, use `GoodJob.perform_inline`.
|
88
|
-
|
89
|
-
For example, using time helpers within an integration test:
|
90
|
-
|
91
|
-
```
|
92
|
-
MyJob.set(wait: 10.minutes).perform_later
|
93
|
-
travel_to(15.minutes.from_now) { GoodJob.perform_inline }
|
94
|
-
```
|
95
|
-
|
96
|
-
Note: Rails `travel`/`travel_to` time helpers do not have millisecond
|
97
|
-
precision, so you must leave at least 1 second between the schedule
|
98
|
-
and time traveling for the job to be executed.
|
99
|
-
DEPRECATION
|
100
|
-
end
|
101
|
-
|
102
59
|
begin
|
103
60
|
result = execution.perform
|
104
61
|
ensure
|
@@ -15,13 +15,13 @@ module GoodJob
|
|
15
15
|
# Default poll interval for async in development environment
|
16
16
|
DEFAULT_DEVELOPMENT_ASYNC_POLL_INTERVAL = -1
|
17
17
|
# Default number of threads to use per {Scheduler}
|
18
|
-
DEFAULT_MAX_CACHE =
|
18
|
+
DEFAULT_MAX_CACHE = 10_000
|
19
19
|
# Default number of seconds to preserve jobs for {CLI#cleanup_preserved_jobs} and {GoodJob.cleanup_preserved_jobs}
|
20
|
-
DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO =
|
20
|
+
DEFAULT_CLEANUP_PRESERVED_JOBS_BEFORE_SECONDS_AGO = 14.days.to_i
|
21
21
|
# Default number of jobs to execute between preserved job cleanup runs
|
22
|
-
DEFAULT_CLEANUP_INTERVAL_JOBS =
|
22
|
+
DEFAULT_CLEANUP_INTERVAL_JOBS = 1_000
|
23
23
|
# Default number of seconds to wait between preserved job cleanup runs
|
24
|
-
DEFAULT_CLEANUP_INTERVAL_SECONDS =
|
24
|
+
DEFAULT_CLEANUP_INTERVAL_SECONDS = 10.minutes.to_i
|
25
25
|
# Default to always wait for jobs to finish for {Adapter#shutdown}
|
26
26
|
DEFAULT_SHUTDOWN_TIMEOUT = -1
|
27
27
|
# Default to not running cron
|
@@ -14,8 +14,6 @@ module GoodJob # :nodoc:
|
|
14
14
|
# Registers the current process.
|
15
15
|
def register_process
|
16
16
|
GoodJob::Process.with_connection(connection) do
|
17
|
-
next unless Process.migrated?
|
18
|
-
|
19
17
|
GoodJob::Process.cleanup
|
20
18
|
@process = GoodJob::Process.register
|
21
19
|
end
|
@@ -24,8 +22,6 @@ module GoodJob # :nodoc:
|
|
24
22
|
# Deregisters the current process.
|
25
23
|
def deregister_process
|
26
24
|
GoodJob::Process.with_connection(connection) do
|
27
|
-
next unless Process.migrated?
|
28
|
-
|
29
25
|
@process&.deregister
|
30
26
|
end
|
31
27
|
end
|
data/lib/good_job/version.rb
CHANGED
data/lib/good_job.rb
CHANGED
@@ -8,6 +8,7 @@ Zeitwerk::Loader.for_gem(**zeitwerk_options).tap do |loader|
|
|
8
8
|
loader.inflector.inflect({
|
9
9
|
"cli" => "CLI",
|
10
10
|
})
|
11
|
+
loader.push_dir("#{__dir__}/models")
|
11
12
|
loader.ignore("#{__dir__}/generators")
|
12
13
|
loader.setup
|
13
14
|
end
|
@@ -42,23 +43,21 @@ module GoodJob
|
|
42
43
|
|
43
44
|
# @!attribute [rw] preserve_job_records
|
44
45
|
# @!scope class
|
45
|
-
# Whether to preserve job records in the database after they have finished (default: +
|
46
|
-
# By default, GoodJob
|
46
|
+
# Whether to preserve job records in the database after they have finished (default: +true+).
|
47
|
+
# By default, GoodJob deletes job records after the job is completed successfully.
|
47
48
|
# If you want to preserve jobs for latter inspection, set this to +true+.
|
48
49
|
# If you want to preserve only jobs that finished with error for latter inspection, set this to +:on_unhandled_error+.
|
49
|
-
# If +true+, you will need to clean out jobs using the +good_job cleanup_preserved_jobs+ CLI command or
|
50
|
-
# by using +Goodjob.cleanup_preserved_jobs+.
|
51
50
|
# @return [Boolean, nil]
|
52
|
-
mattr_accessor :preserve_job_records, default:
|
51
|
+
mattr_accessor :preserve_job_records, default: true
|
53
52
|
|
54
53
|
# @!attribute [rw] retry_on_unhandled_error
|
55
54
|
# @!scope class
|
56
|
-
# Whether to re-perform a job when a type of +StandardError+ is raised to GoodJob (default: +
|
55
|
+
# Whether to re-perform a job when a type of +StandardError+ is raised to GoodJob (default: +false+).
|
57
56
|
# If +true+, causes jobs to be re-queued and retried if they raise an instance of +StandardError+.
|
58
57
|
# If +false+, jobs will be discarded or marked as finished if they raise an instance of +StandardError+.
|
59
58
|
# Instances of +Exception+, like +SIGINT+, will *always* be retried, regardless of this attribute's value.
|
60
59
|
# @return [Boolean, nil]
|
61
|
-
mattr_accessor :retry_on_unhandled_error, default:
|
60
|
+
mattr_accessor :retry_on_unhandled_error, default: false
|
62
61
|
|
63
62
|
# @!attribute [rw] on_thread_error
|
64
63
|
# @!scope class
|
@@ -142,7 +141,7 @@ module GoodJob
|
|
142
141
|
include_discarded = configuration.cleanup_discarded_jobs?
|
143
142
|
|
144
143
|
ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: timestamp }) do |payload|
|
145
|
-
old_jobs = GoodJob::
|
144
|
+
old_jobs = GoodJob::Job.where('finished_at <= ?', timestamp)
|
146
145
|
old_jobs = old_jobs.not_discarded unless include_discarded
|
147
146
|
old_jobs_count = old_jobs.count
|
148
147
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GoodJob
|
3
|
+
# @deprecated Use {GoodJob::Job} instead.
|
4
|
+
class ActiveJobJob < Execution
|
5
|
+
after_initialize do |_job|
|
6
|
+
ActiveSupport::Deprecation.warn(
|
7
|
+
"The `GoodJob::ActiveJobJob` class name is deprecated. Replace with `GoodJob::Job`."
|
8
|
+
)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
File without changes
|
@@ -73,13 +73,13 @@ module GoodJob # :nodoc:
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def jobs
|
76
|
-
GoodJob::
|
76
|
+
GoodJob::Job.where(cron_key: key)
|
77
77
|
end
|
78
78
|
|
79
79
|
def last_at
|
80
80
|
return if last_job.blank?
|
81
81
|
|
82
|
-
if GoodJob::
|
82
|
+
if GoodJob::Job.column_names.include?('cron_at')
|
83
83
|
(last_job.cron_at || last_job.created_at).localtime
|
84
84
|
else
|
85
85
|
last_job.created_at
|
@@ -99,7 +99,7 @@ module GoodJob # :nodoc:
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def last_job
|
102
|
-
if GoodJob::
|
102
|
+
if GoodJob::Job.column_names.include?('cron_at')
|
103
103
|
jobs.order("cron_at DESC NULLS LAST").first
|
104
104
|
else
|
105
105
|
jobs.order(created_at: :asc).last
|
@@ -51,7 +51,7 @@ module GoodJob
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
belongs_to :job, class_name: 'GoodJob::
|
54
|
+
belongs_to :job, class_name: 'GoodJob::Job', foreign_key: 'active_job_id', primary_key: 'active_job_id', optional: true, inverse_of: :executions
|
55
55
|
|
56
56
|
# Get Jobs with given ActiveJob ID
|
57
57
|
# @!method active_job_id
|
@@ -207,14 +207,7 @@ module GoodJob
|
|
207
207
|
|
208
208
|
if CurrentThread.cron_key
|
209
209
|
execution_args[:cron_key] = CurrentThread.cron_key
|
210
|
-
|
211
|
-
@cron_at_index = column_names.include?('cron_at') && connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at) unless instance_variable_defined?(:@cron_at_index)
|
212
|
-
|
213
|
-
if @cron_at_index
|
214
|
-
execution_args[:cron_at] = CurrentThread.cron_at
|
215
|
-
else
|
216
|
-
migration_pending_warning!
|
217
|
-
end
|
210
|
+
execution_args[:cron_at] = CurrentThread.cron_at
|
218
211
|
elsif CurrentThread.active_job_id && CurrentThread.active_job_id == active_job.job_id
|
219
212
|
execution_args[:cron_key] = CurrentThread.execution.cron_key
|
220
213
|
end
|
@@ -346,8 +339,7 @@ module GoodJob
|
|
346
339
|
current_thread.reset
|
347
340
|
current_thread.execution = self
|
348
341
|
|
349
|
-
|
350
|
-
ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
|
342
|
+
ActiveSupport::Notifications.instrument("perform_job.good_job", { execution: self, process_id: current_thread.process_id, thread_name: current_thread.thread_name }) do
|
351
343
|
value = ActiveJob::Base.execute(active_job_data)
|
352
344
|
|
353
345
|
if value.is_a?(Exception)
|
@@ -3,8 +3,8 @@ module GoodJob
|
|
3
3
|
# ActiveRecord model that represents an +ActiveJob+ job.
|
4
4
|
# There is not a table in the database whose discrete rows represents "Jobs".
|
5
5
|
# The +good_jobs+ table is a table of individual {GoodJob::Execution}s that share the same +active_job_id+.
|
6
|
-
# A single row from the +good_jobs+ table of executions is fetched to represent an
|
7
|
-
class
|
6
|
+
# A single row from the +good_jobs+ table of executions is fetched to represent an Job
|
7
|
+
class Job < BaseRecord
|
8
8
|
include Filterable
|
9
9
|
include Lockable
|
10
10
|
|
@@ -26,7 +26,7 @@ module GoodJob
|
|
26
26
|
self.primary_key = 'active_job_id'
|
27
27
|
self.advisory_lockable_column = 'active_job_id'
|
28
28
|
|
29
|
-
has_many :executions, -> { order(created_at: :asc) }, class_name: 'GoodJob::Execution', foreign_key: 'active_job_id', inverse_of: :job
|
29
|
+
has_many :executions, -> { order(created_at: :asc) }, class_name: 'GoodJob::Execution', foreign_key: 'active_job_id', inverse_of: :job
|
30
30
|
|
31
31
|
# Only the most-recent unretried execution represents a "Job"
|
32
32
|
default_scope { where(retried_good_job_id: nil) }
|
@@ -166,7 +166,7 @@ module GoodJob
|
|
166
166
|
|
167
167
|
raise ActionForStateMismatchError if execution.finished_at.present?
|
168
168
|
|
169
|
-
job_error = GoodJob::
|
169
|
+
job_error = GoodJob::Job::DiscardJobError.new(message)
|
170
170
|
|
171
171
|
update_execution = proc do
|
172
172
|
execution.update(
|
File without changes
|
@@ -25,15 +25,6 @@ module GoodJob # :nodoc:
|
|
25
25
|
# @return [ActiveRecord::Relation]
|
26
26
|
scope :inactive, -> { advisory_unlocked }
|
27
27
|
|
28
|
-
# Whether the +good_job_processes+ table exsists.
|
29
|
-
# @return [Boolean]
|
30
|
-
def self.migrated?
|
31
|
-
return true if connection.table_exists?(table_name)
|
32
|
-
|
33
|
-
migration_pending_warning!
|
34
|
-
false
|
35
|
-
end
|
36
|
-
|
37
28
|
# UUID that is unique to the current process and changes when forked.
|
38
29
|
# @return [String]
|
39
30
|
def self.current_id
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: good_job
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-06-
|
11
|
+
date: 2022-06-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version:
|
19
|
+
version: 6.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version:
|
26
|
+
version: 6.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version:
|
33
|
+
version: 6.0.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
40
|
+
version: 6.0.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: concurrent-ruby
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: 6.0.0
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: 6.0.0
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: thor
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,16 +140,16 @@ dependencies:
|
|
140
140
|
name: capybara
|
141
141
|
requirement: !ruby/object:Gem::Requirement
|
142
142
|
requirements:
|
143
|
-
- - "
|
143
|
+
- - ">="
|
144
144
|
- !ruby/object:Gem::Version
|
145
|
-
version:
|
145
|
+
version: '0'
|
146
146
|
type: :development
|
147
147
|
prerelease: false
|
148
148
|
version_requirements: !ruby/object:Gem::Requirement
|
149
149
|
requirements:
|
150
|
-
- - "
|
150
|
+
- - ">="
|
151
151
|
- !ruby/object:Gem::Version
|
152
|
-
version:
|
152
|
+
version: '0'
|
153
153
|
- !ruby/object:Gem::Dependency
|
154
154
|
name: database_cleaner
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
@@ -294,16 +294,16 @@ dependencies:
|
|
294
294
|
name: selenium-webdriver
|
295
295
|
requirement: !ruby/object:Gem::Requirement
|
296
296
|
requirements:
|
297
|
-
- - "
|
297
|
+
- - ">="
|
298
298
|
- !ruby/object:Gem::Version
|
299
|
-
version: '
|
299
|
+
version: '0'
|
300
300
|
type: :development
|
301
301
|
prerelease: false
|
302
302
|
version_requirements: !ruby/object:Gem::Requirement
|
303
303
|
requirements:
|
304
|
-
- - "
|
304
|
+
- - ">="
|
305
305
|
- !ruby/object:Gem::Version
|
306
|
-
version: '
|
306
|
+
version: '0'
|
307
307
|
- !ruby/object:Gem::Dependency
|
308
308
|
name: sigdump
|
309
309
|
requirement: !ruby/object:Gem::Requirement
|
@@ -382,9 +382,6 @@ files:
|
|
382
382
|
- app/filters/good_job/base_filter.rb
|
383
383
|
- app/filters/good_job/jobs_filter.rb
|
384
384
|
- app/helpers/good_job/application_helper.rb
|
385
|
-
- app/models/good_job/active_job_job.rb
|
386
|
-
- app/models/good_job/execution.rb
|
387
|
-
- app/models/good_job/process.rb
|
388
385
|
- app/views/good_job/cron_entries/index.html.erb
|
389
386
|
- app/views/good_job/cron_entries/show.html.erb
|
390
387
|
- app/views/good_job/jobs/_executions.erb
|
@@ -417,21 +414,15 @@ files:
|
|
417
414
|
- lib/generators/good_job/install_generator.rb
|
418
415
|
- lib/generators/good_job/templates/install/migrations/create_good_jobs.rb.erb
|
419
416
|
- lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb
|
420
|
-
- lib/generators/good_job/templates/update/migrations/02_add_cron_at_to_good_jobs.rb.erb
|
421
|
-
- lib/generators/good_job/templates/update/migrations/03_add_cron_key_cron_at_index_to_good_jobs.rb.erb
|
422
|
-
- lib/generators/good_job/templates/update/migrations/04_create_good_job_processes.rb.erb
|
423
|
-
- lib/generators/good_job/templates/update/migrations/04_index_good_job_jobs_on_finished_at.rb.erb
|
424
417
|
- lib/generators/good_job/update_generator.rb
|
425
418
|
- lib/good_job.rb
|
426
419
|
- lib/good_job/active_job_extensions.rb
|
427
420
|
- lib/good_job/active_job_extensions/concurrency.rb
|
428
421
|
- lib/good_job/adapter.rb
|
429
422
|
- lib/good_job/assignable_connection.rb
|
430
|
-
- lib/good_job/base_record.rb
|
431
423
|
- lib/good_job/cleanup_tracker.rb
|
432
424
|
- lib/good_job/cli.rb
|
433
425
|
- lib/good_job/configuration.rb
|
434
|
-
- lib/good_job/cron_entry.rb
|
435
426
|
- lib/good_job/cron_manager.rb
|
436
427
|
- lib/good_job/current_thread.rb
|
437
428
|
- lib/good_job/daemon.rb
|
@@ -439,9 +430,7 @@ files:
|
|
439
430
|
- lib/good_job/engine.rb
|
440
431
|
- lib/good_job/execution_result.rb
|
441
432
|
- lib/good_job/filterable.rb
|
442
|
-
- lib/good_job/job.rb
|
443
433
|
- lib/good_job/job_performer.rb
|
444
|
-
- lib/good_job/lockable.rb
|
445
434
|
- lib/good_job/log_subscriber.rb
|
446
435
|
- lib/good_job/multi_scheduler.rb
|
447
436
|
- lib/good_job/notifier.rb
|
@@ -450,6 +439,13 @@ files:
|
|
450
439
|
- lib/good_job/probe_server.rb
|
451
440
|
- lib/good_job/scheduler.rb
|
452
441
|
- lib/good_job/version.rb
|
442
|
+
- lib/models/good_job/active_job_job.rb
|
443
|
+
- lib/models/good_job/base_record.rb
|
444
|
+
- lib/models/good_job/cron_entry.rb
|
445
|
+
- lib/models/good_job/execution.rb
|
446
|
+
- lib/models/good_job/job.rb
|
447
|
+
- lib/models/good_job/lockable.rb
|
448
|
+
- lib/models/good_job/process.rb
|
453
449
|
homepage: https://github.com/bensheldon/good_job
|
454
450
|
licenses:
|
455
451
|
- MIT
|
@@ -460,7 +456,7 @@ metadata:
|
|
460
456
|
homepage_uri: https://github.com/bensheldon/good_job
|
461
457
|
source_code_uri: https://github.com/bensheldon/good_job
|
462
458
|
rubygems_mfa_required: 'true'
|
463
|
-
post_install_message:
|
459
|
+
post_install_message:
|
464
460
|
rdoc_options:
|
465
461
|
- "--title"
|
466
462
|
- GoodJob - a multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
@@ -482,8 +478,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
482
478
|
- !ruby/object:Gem::Version
|
483
479
|
version: '0'
|
484
480
|
requirements: []
|
485
|
-
rubygems_version: 3.
|
486
|
-
signing_key:
|
481
|
+
rubygems_version: 3.1.6
|
482
|
+
signing_key:
|
487
483
|
specification_version: 4
|
488
484
|
summary: A multithreaded, Postgres-based ActiveJob backend for Ruby on Rails
|
489
485
|
test_files: []
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
class AddCronAtToGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
3
|
-
def change
|
4
|
-
reversible do |dir|
|
5
|
-
dir.up do
|
6
|
-
# Ensure this incremental update migration is idempotent
|
7
|
-
# with monolithic install migration.
|
8
|
-
return if connection.column_exists?(:good_jobs, :cron_at)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
add_column :good_jobs, :cron_at, :timestamp
|
13
|
-
end
|
14
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
class AddCronKeyCronAtIndexToGoodJobs < ActiveRecord::Migration<%= migration_version %>
|
3
|
-
disable_ddl_transaction!
|
4
|
-
|
5
|
-
def change
|
6
|
-
reversible do |dir|
|
7
|
-
dir.up do
|
8
|
-
# Ensure this incremental update migration is idempotent
|
9
|
-
# with monolithic install migration.
|
10
|
-
return if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_cron_key_and_cron_at)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
add_index :good_jobs,
|
15
|
-
[:cron_key, :cron_at],
|
16
|
-
algorithm: :concurrently,
|
17
|
-
name: :index_good_jobs_on_cron_key_and_cron_at,
|
18
|
-
unique: true
|
19
|
-
end
|
20
|
-
end
|
data/lib/generators/good_job/templates/update/migrations/04_create_good_job_processes.rb.erb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
class CreateGoodJobProcesses < ActiveRecord::Migration<%= migration_version %>
|
3
|
-
def change
|
4
|
-
reversible do |dir|
|
5
|
-
dir.up do
|
6
|
-
# Ensure this incremental update migration is idempotent
|
7
|
-
# with monolithic install migration.
|
8
|
-
return if connection.table_exists?(:good_job_processes)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
create_table :good_job_processes, id: :uuid do |t|
|
13
|
-
t.timestamps
|
14
|
-
t.jsonb :state
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
class IndexGoodJobJobsOnFinishedAt < ActiveRecord::Migration<%= migration_version %>
|
3
|
-
disable_ddl_transaction!
|
4
|
-
|
5
|
-
def change
|
6
|
-
reversible do |dir|
|
7
|
-
dir.up do
|
8
|
-
# Ensure this incremental update migration is idempotent
|
9
|
-
# with monolithic install migration.
|
10
|
-
return if connection.index_name_exists?(:good_jobs, :index_good_jobs_on_active_job_id)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
add_index :good_jobs,
|
15
|
-
[:active_job_id],
|
16
|
-
name: :index_good_jobs_on_active_job_id,
|
17
|
-
algorithm: :concurrently
|
18
|
-
|
19
|
-
add_index :good_jobs,
|
20
|
-
[:finished_at],
|
21
|
-
where: "retried_good_job_id IS NULL AND finished_at IS NOT NULL",
|
22
|
-
name: :index_good_jobs_jobs_on_finished_at,
|
23
|
-
algorithm: :concurrently
|
24
|
-
end
|
25
|
-
end
|
data/lib/good_job/job.rb
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GoodJob
|
3
|
-
# @deprecated Use {GoodJob::Execution} instead.
|
4
|
-
class Job < Execution
|
5
|
-
after_initialize do |_job|
|
6
|
-
ActiveSupport::Deprecation.warn(
|
7
|
-
"The `GoodJob::Job` class name is deprecated. Replace with `GoodJob::Execution`."
|
8
|
-
)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|