good_job 1.13.0 → 1.99.1
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 +78 -0
- data/README.md +51 -8
- data/lib/generators/good_job/install_generator.rb +6 -6
- data/lib/generators/good_job/templates/update/migrations/03_add_active_job_id_index_and_concurrency_key_index_to_good_jobs.rb +4 -5
- data/lib/generators/good_job/update_generator.rb +4 -6
- data/lib/good_job/active_job_extensions/concurrency.rb +6 -0
- data/lib/good_job/adapter.rb +1 -1
- data/lib/good_job/configuration.rb +13 -2
- data/lib/good_job/job.rb +7 -1
- data/lib/good_job/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 97662bae9e8ba65e5ed3e9ba52b8b987d77974866885a548a8a3b13878045c7a
|
4
|
+
data.tar.gz: 415d36696796cfb4c0ff1737c7c75e2b66bbfceea15f3a90aba55b49ee5da715
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d293eabb7b926386b30a1348c529de6a2252c1c734b7a92a81abad2fdd791a28abe5067850c9a4f7595182afd72d52eccc0c640d7596aaddcba467a995449ca
|
7
|
+
data.tar.gz: 4b981bda934dc7e58aab80bd998c16b9c8261309cf8f5ffce09253c45821f0106ef0db0249934a3649e735715d865ff6dd62232876afb7ffca76cfb4fe473179
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,83 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v1.99.1](https://github.com/bensheldon/good_job/tree/v1.99.1) (2021-08-27)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.0.1...v1.99.1)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Does Good job support delay method? [\#344](https://github.com/bensheldon/good_job/issues/344)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- README style/typo fixes: "web server" and possessive "Rails'" [\#350](https://github.com/bensheldon/good_job/pull/350) ([aried3r](https://github.com/aried3r))
|
14
|
+
- Add examples of setting config.good\_job.queues [\#349](https://github.com/bensheldon/good_job/pull/349) ([zachmargolis](https://github.com/zachmargolis))
|
15
|
+
|
16
|
+
## [v2.0.1](https://github.com/bensheldon/good_job/tree/v2.0.1) (2021-08-24)
|
17
|
+
|
18
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v2.0.0...v2.0.1)
|
19
|
+
|
20
|
+
**Implemented enhancements:**
|
21
|
+
|
22
|
+
- Suppress backtrace of ConcurrencyExceededError [\#348](https://github.com/bensheldon/good_job/pull/348) ([reczy](https://github.com/reczy))
|
23
|
+
|
24
|
+
**Closed issues:**
|
25
|
+
|
26
|
+
- Is there any value in seeing a backtrace for ConcurrencyExceededError? [\#347](https://github.com/bensheldon/good_job/issues/347)
|
27
|
+
- Release GoodJob 2.0 [\#307](https://github.com/bensheldon/good_job/issues/307)
|
28
|
+
- Unhandled ActiveJob errors should trigger GoodJob.on\_thread\_error [\#247](https://github.com/bensheldon/good_job/issues/247)
|
29
|
+
|
30
|
+
## [v2.0.0](https://github.com/bensheldon/good_job/tree/v2.0.0) (2021-08-24)
|
31
|
+
|
32
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.99.0...v2.0.0)
|
33
|
+
|
34
|
+
**Implemented enhancements:**
|
35
|
+
|
36
|
+
- Concurrency's enqueue\_limit should exclude performing jobs from count [\#317](https://github.com/bensheldon/good_job/issues/317)
|
37
|
+
- Rename `:async` to `:async_all`; `:async_server` to `:async` and set as Development environment default; do not poll in async development [\#343](https://github.com/bensheldon/good_job/pull/343) ([bensheldon](https://github.com/bensheldon))
|
38
|
+
- Exclude executing jobs from Concurrency's enqueue\_limit's count [\#342](https://github.com/bensheldon/good_job/pull/342) ([bensheldon](https://github.com/bensheldon))
|
39
|
+
- Unhandled ActiveJob errors should trigger GoodJob.on\_thread\_error [\#312](https://github.com/bensheldon/good_job/pull/312) ([bensheldon](https://github.com/bensheldon))
|
40
|
+
|
41
|
+
**Closed issues:**
|
42
|
+
|
43
|
+
- Swap behavior of `async` with `async_server`; rename `async` execution mode to be `async_all`; default `async` in Development; [\#340](https://github.com/bensheldon/good_job/issues/340)
|
44
|
+
- Add hyphen to lock key. e.g. "\[table\_name\]-\[column\]" instead of "\[table\_name\]\[column\]" [\#335](https://github.com/bensheldon/good_job/issues/335)
|
45
|
+
- Use `async_server` as default execution mode in Development environment [\#139](https://github.com/bensheldon/good_job/issues/139)
|
46
|
+
|
47
|
+
**Merged pull requests:**
|
48
|
+
|
49
|
+
- Remove v1.0 deprecation notices and incremental migrations [\#338](https://github.com/bensheldon/good_job/pull/338) ([bensheldon](https://github.com/bensheldon))
|
50
|
+
- Lock GoodJob::Job on active\_job\_id instead of the row id; adds separator hyphen to lock key [\#337](https://github.com/bensheldon/good_job/pull/337) ([bensheldon](https://github.com/bensheldon))
|
51
|
+
|
52
|
+
## [v1.99.0](https://github.com/bensheldon/good_job/tree/v1.99.0) (2021-08-24)
|
53
|
+
|
54
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.13.2...v1.99.0)
|
55
|
+
|
56
|
+
**Closed issues:**
|
57
|
+
|
58
|
+
- Set Advisory Lock on ActiveJob job uuid instead of GoodJob's job uuid [\#272](https://github.com/bensheldon/good_job/issues/272)
|
59
|
+
|
60
|
+
**Merged pull requests:**
|
61
|
+
|
62
|
+
- Add upgrade instructions for v1 to v2 [\#345](https://github.com/bensheldon/good_job/pull/345) ([bensheldon](https://github.com/bensheldon))
|
63
|
+
- Add transitional/temporary additional lock on good\_jobs-\[active\_job\_id\] [\#336](https://github.com/bensheldon/good_job/pull/336) ([bensheldon](https://github.com/bensheldon))
|
64
|
+
|
65
|
+
## [v1.13.2](https://github.com/bensheldon/good_job/tree/v1.13.2) (2021-08-18)
|
66
|
+
|
67
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.13.1...v1.13.2)
|
68
|
+
|
69
|
+
**Merged pull requests:**
|
70
|
+
|
71
|
+
- Add deprecation notice that `async` mode will be renamed `async_all` in GoodJob v2.0 [\#339](https://github.com/bensheldon/good_job/pull/339) ([bensheldon](https://github.com/bensheldon))
|
72
|
+
|
73
|
+
## [v1.13.1](https://github.com/bensheldon/good_job/tree/v1.13.1) (2021-08-18)
|
74
|
+
|
75
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.13.0...v1.13.1)
|
76
|
+
|
77
|
+
**Fixed bugs:**
|
78
|
+
|
79
|
+
- Don’t attempt to enforce concurrency limits with other queue adapters [\#333](https://github.com/bensheldon/good_job/pull/333) ([codyrobbins](https://github.com/codyrobbins))
|
80
|
+
|
3
81
|
## [v1.13.0](https://github.com/bensheldon/good_job/tree/v1.13.0) (2021-08-18)
|
4
82
|
|
5
83
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.12.2...v1.13.0)
|
data/README.md
CHANGED
@@ -41,6 +41,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
41
41
|
- [ActiveJob concurrency](#activejob-concurrency)
|
42
42
|
- [Cron-style repeating/recurring jobs](#cron-style-repeatingrecurring-jobs)
|
43
43
|
- [Updating](#updating)
|
44
|
+
- [Upgrading minor versions](#upgrading-minor-versions)
|
45
|
+
- [Upgrading v1 to v2](#upgrading-v1-to-v2)
|
44
46
|
- [Go deeper](#go-deeper)
|
45
47
|
- [Exceptions, retries, and reliability](#exceptions-retries-and-reliability)
|
46
48
|
- [Exceptions](#exceptions)
|
@@ -84,6 +86,13 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
84
86
|
$ bin/rails db:migrate
|
85
87
|
```
|
86
88
|
|
89
|
+
Optional: If using Rails' multiple databases with the `migrations_paths` configuration option, use the `--database` option:
|
90
|
+
|
91
|
+
```bash
|
92
|
+
bin/rails g good_job:install --database animals
|
93
|
+
bin/rails db:migrate:animals
|
94
|
+
```
|
95
|
+
|
87
96
|
1. Configure the ActiveJob adapter:
|
88
97
|
|
89
98
|
```ruby
|
@@ -405,17 +414,51 @@ config.good_job.cron = {
|
|
405
414
|
|
406
415
|
GoodJob follows semantic versioning, though updates may be encouraged through deprecation warnings in minor versions.
|
407
416
|
|
408
|
-
|
417
|
+
#### Upgrading minor versions
|
409
418
|
|
410
|
-
|
411
|
-
bin/rails g good_job:update
|
412
|
-
```
|
419
|
+
Upgrading between minor versions (e.g. v1.4 to v1.5) should not introduce breaking changes, but can introduce new deprecation warnings and database migration notices.
|
413
420
|
|
414
|
-
|
421
|
+
To perform upgrades to the GoodJob database tables:
|
415
422
|
|
416
|
-
|
417
|
-
|
418
|
-
```
|
423
|
+
1. Generate new database migration files:
|
424
|
+
|
425
|
+
```bash
|
426
|
+
bin/rails g good_job:update
|
427
|
+
```
|
428
|
+
|
429
|
+
Optional: If using Rails' multiple databases with the `migrations_paths` configuration option, use the `--database` option:
|
430
|
+
|
431
|
+
```bash
|
432
|
+
$ bin/rails g good_job:update --database animals
|
433
|
+
```
|
434
|
+
|
435
|
+
1. Run the database migration locally
|
436
|
+
|
437
|
+
```bash
|
438
|
+
bin/rails db:migrate
|
439
|
+
```
|
440
|
+
|
441
|
+
1. Commit the migration files and resulting `db/schema.rb` changes.
|
442
|
+
1. Deploy the code, run the migrations against the production database, and restart server/worker processes.
|
443
|
+
|
444
|
+
#### Upgrading v1 to v2
|
445
|
+
|
446
|
+
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 likely44
|
447
|
+
necessary.
|
448
|
+
|
449
|
+
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.
|
450
|
+
1. Address any deprecation warnings generated by `v1.99`.
|
451
|
+
1. Upgrade your production environment to `v1.99.x` to `v2.0.x` again following the _minor_ upgrade process.
|
452
|
+
|
453
|
+
Notable changes:
|
454
|
+
|
455
|
+
- Renames `:async_server` execution mode to `:async`; renames prior `:async` execution mode to `:async_all`.
|
456
|
+
- Sets default Development environment's execution mode to `:async` with disabled polling.
|
457
|
+
- Triggers `GoodJob.on_thread_error` for unhandled ActiveJob exceptions.
|
458
|
+
- Renames `GoodJob.reperform_jobs_on_standard_error` accessor to `GoodJob.retry_on_unhandled_error`.
|
459
|
+
- Renames `GoodJob::Adapter.shutdown(wait:)` argument to `GoodJob::Adapter.shutdown(timeout:)`.
|
460
|
+
- Changes Advisory Lock key format from `good_jobs[ROW_ID]` to `good_jobs-[ACTIVE_JOB_ID]`.
|
461
|
+
- Expects presence of columns `good_jobs.active_job_id`, `good_jobs.concurrency_key`, `good_jobs.concurrency_key`, and `good_jobs.retried_good_job_id`.
|
419
462
|
|
420
463
|
## Go deeper
|
421
464
|
|
@@ -1,23 +1,23 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'rails/generators'
|
3
3
|
require 'rails/generators/active_record'
|
4
|
+
|
4
5
|
module GoodJob
|
5
6
|
#
|
6
7
|
# Rails generator used for setting up GoodJob in a Rails application.
|
7
8
|
# Run it with +bin/rails g good_job:install+ in your console.
|
8
9
|
#
|
9
10
|
class InstallGenerator < Rails::Generators::Base
|
10
|
-
include
|
11
|
+
include ActiveRecord::Generators::Migration
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
end
|
13
|
+
TEMPLATES = File.join(File.dirname(__FILE__), "templates/install")
|
14
|
+
source_paths << TEMPLATES
|
15
15
|
|
16
|
-
|
16
|
+
class_option :database, type: :string, aliases: %i(--db), desc: "The database for your migration. By default, the current environment's primary database is used."
|
17
17
|
|
18
18
|
# Generates monolithic migration file that contains all database changes.
|
19
19
|
def create_migration_file
|
20
|
-
migration_template 'migrations/create_good_jobs.rb.erb',
|
20
|
+
migration_template 'migrations/create_good_jobs.rb.erb', File.join(db_migrate_path, "create_good_jobs.rb")
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -4,10 +4,6 @@ class AddActiveJobIdIndexAndConcurrencyKeyIndexToGoodJobs < ActiveRecord::Migrat
|
|
4
4
|
|
5
5
|
UPDATE_BATCH_SIZE = 1_000
|
6
6
|
|
7
|
-
class GoodJobJobs < ActiveRecord::Base
|
8
|
-
self.table_name = "good_jobs"
|
9
|
-
end
|
10
|
-
|
11
7
|
def change
|
12
8
|
reversible do |dir|
|
13
9
|
dir.up do
|
@@ -21,11 +17,14 @@ class AddActiveJobIdIndexAndConcurrencyKeyIndexToGoodJobs < ActiveRecord::Migrat
|
|
21
17
|
add_index :good_jobs, :concurrency_key, where: "(finished_at IS NULL)", algorithm: :concurrently, name: :index_good_jobs_on_concurrency_key_when_unfinished
|
22
18
|
add_index :good_jobs, [:cron_key, :created_at], algorithm: :concurrently, name: :index_good_jobs_on_cron_key_and_created_at
|
23
19
|
|
20
|
+
return unless defined? GoodJob::Job
|
21
|
+
|
24
22
|
reversible do |dir|
|
25
23
|
dir.up do
|
24
|
+
# Ensure that all `good_jobs` records have an active_job_id value
|
26
25
|
start_time = Time.current
|
27
26
|
loop do
|
28
|
-
break if
|
27
|
+
break if GoodJob::Job.where(active_job_id: nil, finished_at: nil).where("created_at < ?", start_time).limit(UPDATE_BATCH_SIZE).update_all("active_job_id = (serialized_params->>'job_id')::uuid").zero?
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
@@ -8,22 +8,20 @@ module GoodJob
|
|
8
8
|
# Run it with +bin/rails g good_job:update+ in your console.
|
9
9
|
#
|
10
10
|
class UpdateGenerator < Rails::Generators::Base
|
11
|
-
include
|
12
|
-
|
13
|
-
class << self
|
14
|
-
delegate :next_migration_number, to: ActiveRecord::Generators::Base
|
15
|
-
end
|
11
|
+
include ActiveRecord::Generators::Migration
|
16
12
|
|
17
13
|
TEMPLATES = File.join(File.dirname(__FILE__), "templates/update")
|
18
14
|
source_paths << TEMPLATES
|
19
15
|
|
16
|
+
class_option :database, type: :string, aliases: %i(--db), desc: "The database for your migration. By default, the current environment's primary database is used."
|
17
|
+
|
20
18
|
# Generates incremental migration files unless they already exist.
|
21
19
|
# All migrations should be idempotent e.g. +add_index+ is guarded with +if_index_exists?+
|
22
20
|
def update_migration_files
|
23
21
|
migration_templates = Dir.children(File.join(TEMPLATES, 'migrations')).sort
|
24
22
|
migration_templates.each do |template_file|
|
25
23
|
destination_file = template_file.match(/^\d*_(.*\.rb)/)[1] # 01_create_good_jobs.rb.erb => create_good_jobs.rb
|
26
|
-
migration_template "migrations/#{template_file}",
|
24
|
+
migration_template "migrations/#{template_file}", File.join(db_migrate_path, destination_file), skip: true
|
27
25
|
end
|
28
26
|
end
|
29
27
|
end
|
@@ -10,6 +10,9 @@ module GoodJob
|
|
10
10
|
class_attribute :good_job_concurrency_config, instance_accessor: false, default: {}
|
11
11
|
|
12
12
|
around_enqueue do |job, block|
|
13
|
+
# Don't attempt to enforce concurrency limits with other queue adapters.
|
14
|
+
next(block.call) unless job.class.queue_adapter.is_a?(GoodJob::Adapter)
|
15
|
+
|
13
16
|
# Always allow jobs to be retried because the current job's execution will complete momentarily
|
14
17
|
next(block.call) if CurrentExecution.active_job_id == job.job_id
|
15
18
|
|
@@ -34,6 +37,9 @@ module GoodJob
|
|
34
37
|
)
|
35
38
|
|
36
39
|
before_perform do |job|
|
40
|
+
# Don't attempt to enforce concurrency limits with other queue adapters.
|
41
|
+
next unless job.class.queue_adapter.is_a?(GoodJob::Adapter)
|
42
|
+
|
37
43
|
limit = job.class.good_job_concurrency_config.fetch(:perform_limit, Float::INFINITY)
|
38
44
|
next if limit.blank? || (0...Float::INFINITY).exclude?(limit)
|
39
45
|
|
data/lib/good_job/adapter.rb
CHANGED
@@ -130,7 +130,7 @@ module GoodJob
|
|
130
130
|
# Whether in +:async+ execution mode.
|
131
131
|
# @return [Boolean]
|
132
132
|
def execute_async?
|
133
|
-
@configuration.execution_mode
|
133
|
+
@configuration.execution_mode.in?([:async, :async_all]) ||
|
134
134
|
@configuration.execution_mode == :async_server && in_server_process?
|
135
135
|
end
|
136
136
|
|
@@ -7,7 +7,7 @@ module GoodJob
|
|
7
7
|
#
|
8
8
|
class Configuration
|
9
9
|
# Valid execution modes.
|
10
|
-
EXECUTION_MODES = [:async, :async_server, :external, :inline].freeze
|
10
|
+
EXECUTION_MODES = [:async, :async_all, :async_server, :external, :inline].freeze
|
11
11
|
# Default number of threads to use per {Scheduler}
|
12
12
|
DEFAULT_MAX_THREADS = 5
|
13
13
|
# Default number of seconds between polls for jobs
|
@@ -58,7 +58,18 @@ module GoodJob
|
|
58
58
|
end
|
59
59
|
|
60
60
|
if mode
|
61
|
-
mode.to_sym
|
61
|
+
mode_sym = mode.to_sym
|
62
|
+
if mode_sym == :async
|
63
|
+
ActiveSupport::Deprecation.warn <<~DEPRECATION
|
64
|
+
The next major version of GoodJob will redefine the meaning of 'async'
|
65
|
+
execution mode to be equivalent to 'async_server' and only execute
|
66
|
+
within the webserver process.
|
67
|
+
|
68
|
+
To continue using the v1.0 semantics of 'async', use `async_all` instead.
|
69
|
+
|
70
|
+
DEPRECATION
|
71
|
+
end
|
72
|
+
mode_sym
|
62
73
|
elsif Rails.env.development? || Rails.env.test?
|
63
74
|
:inline
|
64
75
|
else
|
data/lib/good_job/job.rb
CHANGED
@@ -189,7 +189,13 @@ module GoodJob
|
|
189
189
|
break if good_job.blank?
|
190
190
|
break :unlocked unless good_job&.executable?
|
191
191
|
|
192
|
-
|
192
|
+
begin
|
193
|
+
good_job.with_advisory_lock(key: "good_jobs-#{good_job.active_job_id}") do
|
194
|
+
good_job.perform
|
195
|
+
end
|
196
|
+
rescue RecordAlreadyAdvisoryLockedError => e
|
197
|
+
ExecutionResult.new(value: nil, handled_error: e)
|
198
|
+
end
|
193
199
|
end
|
194
200
|
end
|
195
201
|
|
data/lib/good_job/version.rb
CHANGED
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: 1.
|
4
|
+
version: 1.99.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Sheldon
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-08-
|
11
|
+
date: 2021-08-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|