good_job 2.17.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -0
  3. data/README.md +45 -26
  4. data/app/charts/good_job/scheduled_by_queue_chart.rb +1 -1
  5. data/app/controllers/good_job/jobs_controller.rb +11 -11
  6. data/app/controllers/good_job/processes_controller.rb +1 -1
  7. data/app/filters/good_job/jobs_filter.rb +2 -2
  8. data/app/views/good_job/processes/index.html.erb +1 -9
  9. data/app/views/layouts/good_job/application.html.erb +1 -1
  10. data/lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb.erb +9 -0
  11. data/lib/good_job/adapter.rb +6 -49
  12. data/lib/good_job/configuration.rb +4 -4
  13. data/lib/good_job/current_thread.rb +2 -2
  14. data/lib/good_job/notifier/process_registration.rb +0 -4
  15. data/lib/good_job/version.rb +1 -1
  16. data/lib/good_job.rb +7 -8
  17. data/lib/models/good_job/active_job_job.rb +11 -0
  18. data/lib/{good_job → models/good_job}/base_record.rb +0 -0
  19. data/lib/{good_job → models/good_job}/cron_entry.rb +3 -3
  20. data/{app → lib}/models/good_job/execution.rb +3 -11
  21. data/{app/models/good_job/active_job_job.rb → lib/models/good_job/job.rb} +4 -4
  22. data/lib/{good_job → models/good_job}/lockable.rb +0 -0
  23. data/{app → lib}/models/good_job/process.rb +0 -9
  24. metadata +27 -31
  25. data/lib/generators/good_job/templates/update/migrations/02_add_cron_at_to_good_jobs.rb.erb +0 -14
  26. data/lib/generators/good_job/templates/update/migrations/03_add_cron_key_cron_at_index_to_good_jobs.rb.erb +0 -20
  27. data/lib/generators/good_job/templates/update/migrations/04_create_good_job_processes.rb.erb +0 -17
  28. data/lib/generators/good_job/templates/update/migrations/04_index_good_job_jobs_on_finished_at.rb.erb +0 -25
  29. data/lib/good_job/job.rb +0 -11
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92c29f2bed6e36f449e880b5433c089351c63d1365cdc094b774122202407fb3
4
- data.tar.gz: 4125a6cfb9e3c0d3de88bd8cdfb64acb450f8c6072fc2aa6a0907f9b51083add
3
+ metadata.gz: a4f4e14bae83760bdeb35557a727116d053e47a9b7dbf501914606dbc45c2ef7
4
+ data.tar.gz: c06e9165b7ac5d87af0ab75291fedd0194018752f34332c1a16930ddca53e3dd
5
5
  SHA512:
6
- metadata.gz: cd6b4fbce879de227852b9399bbb65739933b50732dfc5be5a3563162c55375d1d366d4796bf163c4d12683a7f03668ef7a80d73e229343debe622c7e7ccd2b1
7
- data.tar.gz: 5f4fac41e04a0844b93cc482e24b910e599ccabf411ac6841e7519cb6d573a6d7bb82070f6a35ffc40a1937256f910e9e6995cc5a9090e779c9b2eac33a8d901
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:** 5.2+
147
- - **Ruby:** MRI 2.5+. JRuby 9.2.13+
148
- - **Postgres:** 9.6+
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: `false`)
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: `false`)
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: `true`)
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 will automatically and immediately retry a job when an exception is raised to GoodJob.
565
+ By default, GoodJob relies on ActiveJob's retry functionality.
551
566
 
552
- However, 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:
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. GoodJob can be configured to discard un-handled exceptions instead of retrying them. Be aware that if NOT setting `retry_on_unhandled_error` to `false` good_job will by default retry the failing job and may do this infinitely without pause thereby at least causing high load. In most cases `retry_on_unhandled_error` should be set as following:
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` (`ActionMailer::DeliveryJob` in Rails 5.2 or earlier) because ActionMailer uses a custom class, `ActionMailer::MailDeliveryJob`, which inherits from `ActiveJob::Base`, rather than your applications `ApplicationJob`.
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 destroy job records 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`).
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 necessary to destroy these preserved jobs from the database after a certain time period:
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 keep 1 day of job records by default.
870
- GoodJob.cleanup_preserved_jobs(older_than: 7.days) # It also takes custom arguments.
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::ActiveJobJob.table_name
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::ActiveJobJob::AdapterNotGoodJobError,
14
- GoodJob::ActiveJobJob::ActionForStateMismatchError,
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
- ActiveJobJob.where(active_job_id: job_ids)
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::ActiveJobJob::ActionForStateMismatchError
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 = ActiveJobJob.find(params[:id])
59
+ @job = Job.find(params[:id])
60
60
  end
61
61
 
62
62
  def discard
63
- @job = ActiveJobJob.find(params[:id])
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 = ActiveJobJob.find(params[:id])
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 = ActiveJobJob.find(params[:id])
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 = ActiveJobJob.find(params[:id])
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::ActiveJobJob::AdapterNotGoodJobError
90
+ when GoodJob::Job::AdapterNotGoodJobError
91
91
  "ActiveJob Queue Adapter must be GoodJob."
92
- when GoodJob::ActiveJobJob::ActionForStateMismatchError
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
@@ -2,7 +2,7 @@
2
2
  module GoodJob
3
3
  class ProcessesController < GoodJob::ApplicationController
4
4
  def index
5
- @processes = GoodJob::Process.active.order(created_at: :desc) if GoodJob::Process.migrated?
5
+ @processes = GoodJob::Process.active.order(created_at: :desc)
6
6
  end
7
7
  end
8
8
  end
@@ -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::ActiveJobJob.table_name}.*", 'pg_locks.locktype')
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::ActiveJobJob.all
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 !GoodJob::Process.migrated? %>
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.each_with_object({}) { |module_name, imports| imports[module_name] = modules_path(module_name, format: :js, locale: nil, v: GoodJob::VERSION) } } %>
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
@@ -20,32 +20,16 @@ module GoodJob
20
20
  #
21
21
  # The default value depends on the Rails environment:
22
22
  #
23
- # - +development+ and +test+: +:inline+
23
+ # - +development+: +:async:+
24
+ # -+test+: +:inline+
24
25
  # - +production+ and all other environments: +:external+
25
26
  #
26
- # @param max_threads [Integer, nil] sets the number of threads per scheduler to use when +execution_mode+ is set to +:async+. The +queues+ parameter can specify a number of threads for each group of queues which will override this value. You can also set this with the environment variable +GOOD_JOB_MAX_THREADS+. Defaults to +5+.
27
- # @param queues [String, nil] determines which queues to execute jobs from when +execution_mode+ is set to +:async+. See {file:README.md#optimize-queues-threads-and-processes} for more details on the format of this string. You can also set this with the environment variable +GOOD_JOB_QUEUES+. Defaults to +"*"+.
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 start_async_on_initialize || GoodJob.async_ready?
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 = 10000
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 = 24 * 60 * 60
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 = nil
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 = nil
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
@@ -56,8 +56,8 @@ module GoodJob
56
56
  # Exports values to hash
57
57
  # @return [Hash]
58
58
  def self.to_h
59
- ACCESSORS.each_with_object({}) do |accessor, hash|
60
- hash[accessor] = send(accessor)
59
+ ACCESSORS.index_with do |accessor|
60
+ send(accessor)
61
61
  end
62
62
  end
63
63
 
@@ -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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '2.17.0'
4
+ VERSION = '3.0.0'
5
5
  end
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: +false+).
46
- # By default, GoodJob destroys job records after the job is completed successfully.
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: false
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: +true+).
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: true
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::ActiveJobJob.where('finished_at <= ?', timestamp)
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::ActiveJobJob.where(cron_key: key)
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::ActiveJobJob.column_names.include?('cron_at')
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::ActiveJobJob.column_names.include?('cron_at')
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::ActiveJobJob', foreign_key: 'active_job_id', primary_key: 'active_job_id', optional: true, inverse_of: :executions
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
- # DEPRECATION: Remove deprecated `good_job:` parameter in GoodJob v3
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 ActiveJobJob
7
- class ActiveJobJob < BaseRecord
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 # rubocop:disable Rails/HasManyOrHasOneDependent
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::ActiveJobJob::DiscardJobError.new(message)
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: 2.17.0
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-23 00:00:00.000000000 Z
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: 5.2.0
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: 5.2.0
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: 5.2.0
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: 5.2.0
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: 5.2.0
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: 5.2.0
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: 3.35.0
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: 3.35.0
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: '3.142'
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: '3.142'
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.3.16
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
@@ -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