good_job 4.1.1 → 4.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +44 -0
- data/README.md +10 -10
- data/app/controllers/good_job/batches_controller.rb +6 -0
- data/app/controllers/good_job/jobs_controller.rb +1 -1
- data/app/models/concerns/good_job/error_events.rb +2 -2
- data/app/models/good_job/base_record.rb +1 -0
- data/app/models/good_job/batch.rb +21 -4
- data/app/models/good_job/batch_record.rb +1 -5
- data/app/models/good_job/job.rb +3 -27
- data/app/models/good_job/process.rb +14 -3
- data/app/views/good_job/batches/_table.erb +6 -0
- data/app/views/good_job/batches/show.html.erb +8 -0
- data/config/locales/de.yml +5 -0
- data/config/locales/en.yml +5 -0
- data/config/locales/es.yml +5 -0
- data/config/locales/fr.yml +5 -0
- data/config/locales/it.yml +5 -0
- data/config/locales/ja.yml +10 -5
- data/config/locales/ko.yml +9 -4
- data/config/locales/nl.yml +5 -0
- data/config/locales/pt-BR.yml +5 -0
- data/config/locales/ru.yml +5 -0
- data/config/locales/tr.yml +5 -0
- data/config/locales/uk.yml +6 -1
- data/config/routes.rb +6 -2
- data/lib/good_job/active_job_extensions/concurrency.rb +8 -4
- data/lib/good_job/capsule_tracker.rb +2 -2
- data/lib/good_job/configuration.rb +10 -8
- data/lib/good_job/notifier/process_heartbeat.rb +3 -2
- 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: f21cb4322491fa83f330857033b5c1c0524509d57a93d795d3e4c7ce064e676c
|
4
|
+
data.tar.gz: '05082cbbd0fd4a26587ac53a58d7042c546390505e68fb978ef675bdfe6a0fa6'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 825bed536a7ee957773981cc926f04dad400e0f2a770e5749a18511927b3c09a4130370a5ee0d88e984bf8ed3a09cce53bd0285bc1066c1e4a837835ee44ab21
|
7
|
+
data.tar.gz: 04371b7bb7fb075dc5d11817ff942443609bfd33cd7112ba35c9617447ae520035d7fcfafff127e170b77dba4d258af5ebc54448c9d20c07cd1516d584076fdb
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,49 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v4.2.1](https://github.com/bensheldon/good_job/tree/v4.2.1) (2024-08-29)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.2.0...v4.2.1)
|
6
|
+
|
7
|
+
**Closed issues:**
|
8
|
+
|
9
|
+
- Issue with active\_record.strict\_loading\_by\_default [\#1474](https://github.com/bensheldon/good_job/issues/1474)
|
10
|
+
|
11
|
+
**Merged pull requests:**
|
12
|
+
|
13
|
+
- fix strict\_loading\_by\_default in BaseRecord [\#1475](https://github.com/bensheldon/good_job/pull/1475) ([emilsosa](https://github.com/emilsosa))
|
14
|
+
- Bump rexml from 3.3.3 to 3.3.6 [\#1473](https://github.com/bensheldon/good_job/pull/1473) ([dependabot[bot]](https://github.com/apps/dependabot))
|
15
|
+
- Bump fugit from 1.11.0 to 1.11.1 [\#1471](https://github.com/bensheldon/good_job/pull/1471) ([dependabot[bot]](https://github.com/apps/dependabot))
|
16
|
+
|
17
|
+
## [v4.2.0](https://github.com/bensheldon/good_job/tree/v4.2.0) (2024-08-16)
|
18
|
+
|
19
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.1.1...v4.2.0)
|
20
|
+
|
21
|
+
**Implemented enhancements:**
|
22
|
+
|
23
|
+
- Add retry functionality for batches [\#1456](https://github.com/bensheldon/good_job/pull/1456) ([bensheldon](https://github.com/bensheldon))
|
24
|
+
|
25
|
+
**Fixed bugs:**
|
26
|
+
|
27
|
+
- respect perform\_throttle even if perform\_limit is provided [\#1470](https://github.com/bensheldon/good_job/pull/1470) ([doits](https://github.com/doits))
|
28
|
+
- Do not use advisory lock on heartbeat in production [\#1451](https://github.com/bensheldon/good_job/pull/1451) ([bensheldon](https://github.com/bensheldon))
|
29
|
+
|
30
|
+
**Closed issues:**
|
31
|
+
|
32
|
+
- `perform_limit` and `perform_throttle` don't work both [\#1469](https://github.com/bensheldon/good_job/issues/1469)
|
33
|
+
- Edge rails changes breaking binding commits [\#1466](https://github.com/bensheldon/good_job/issues/1466)
|
34
|
+
- Dynamic creation of CronEntries [\#1457](https://github.com/bensheldon/good_job/issues/1457)
|
35
|
+
- Batch callback job not enqueued after success of retried job [\#1450](https://github.com/bensheldon/good_job/issues/1450)
|
36
|
+
|
37
|
+
**Merged pull requests:**
|
38
|
+
|
39
|
+
- Update cron documentation to remove confusion about multiple processes [\#1467](https://github.com/bensheldon/good_job/pull/1467) ([bensheldon](https://github.com/bensheldon))
|
40
|
+
- Update compatibility matrix, remove compatibility code [\#1465](https://github.com/bensheldon/good_job/pull/1465) ([Earlopain](https://github.com/Earlopain))
|
41
|
+
- Run tests with warnings enabled [\#1462](https://github.com/bensheldon/good_job/pull/1462) ([Earlopain](https://github.com/Earlopain))
|
42
|
+
- Add appraisal for Rails 7.2; bracket lowest PG version instead of enumerating all [\#1460](https://github.com/bensheldon/good_job/pull/1460) ([bensheldon](https://github.com/bensheldon))
|
43
|
+
- Fix a few method redefinition warnings [\#1459](https://github.com/bensheldon/good_job/pull/1459) ([Earlopain](https://github.com/Earlopain))
|
44
|
+
- Bump rexml from 3.3.2 to 3.3.3 [\#1455](https://github.com/bensheldon/good_job/pull/1455) ([dependabot[bot]](https://github.com/apps/dependabot))
|
45
|
+
- Remove `smaller_number_is_higher_priority` option from v4 [\#1453](https://github.com/bensheldon/good_job/pull/1453) ([bensheldon](https://github.com/bensheldon))
|
46
|
+
|
3
47
|
## [v4.1.1](https://github.com/bensheldon/good_job/tree/v4.1.1) (2024-07-31)
|
4
48
|
|
5
49
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v1.99.2...v4.1.1)
|
data/README.md
CHANGED
@@ -164,8 +164,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
|
|
164
164
|
|
165
165
|
## Compatibility
|
166
166
|
|
167
|
-
- **Ruby on Rails:** 6.
|
168
|
-
- **Ruby:** Ruby
|
167
|
+
- **Ruby on Rails:** 6.1+
|
168
|
+
- **Ruby:** Ruby 3.0+. JRuby 9.4+
|
169
169
|
- **Postgres:** 10.0+
|
170
170
|
|
171
171
|
## Configuration
|
@@ -307,7 +307,7 @@ Available configuration options are:
|
|
307
307
|
- `inline_execution_respects_schedule` (boolean) Opt-in to future behavior of inline execution respecting scheduled jobs. Defaults to `false`.
|
308
308
|
- `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`).
|
309
309
|
- `preserve_job_records` (boolean) keeps job records in your database even after jobs are completed. (Default: `true`)
|
310
|
-
- `
|
310
|
+
- `advisory_lock_heartbeat` (boolean) whether to use an advisory lock for the purpose of determining whether an execeution process is active. (Default `true` in Development; `false` in other environments)
|
311
311
|
- `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`)
|
312
312
|
- `on_thread_error` (proc, lambda, or callable) will be called when there is an Exception. It can be useful for logging errors to bug tracking services, like Sentry or Airbrake. Example:
|
313
313
|
|
@@ -499,7 +499,9 @@ As a second example, you may wish to show a link to a log aggregator next to eac
|
|
499
499
|
|
500
500
|
### Job priority
|
501
501
|
|
502
|
-
|
502
|
+
Smaller `priority` values have higher priority and run first (default: `0`), in accordance with [Active Job's definition of priority](https://github.com/rails/rails/blob/e17faead4f2aff28da079d50f02ea5b015322d5b/activejob/lib/active_job/core.rb#L22).
|
503
|
+
|
504
|
+
Prior to GoodJob v4, this was reversed: higher priority numbers ran first in all versions of GoodJob v3.x and below. When migrating from v3 to v4, new behavior can be opted into by setting `config.good_job.smaller_number_is_higher_priority = true` in your GoodJob initializer or `application.rb`.
|
503
505
|
|
504
506
|
### Labelled jobs
|
505
507
|
|
@@ -611,9 +613,7 @@ GoodJob's concurrency control strategy for `perform_limit` is "optimistic retry
|
|
611
613
|
|
612
614
|
GoodJob can enqueue Active Job jobs on a recurring basis that can be used as a replacement for cron.
|
613
615
|
|
614
|
-
Cron-style jobs can be
|
615
|
-
|
616
|
-
GoodJob's cron uses unique indexes to ensure that only a single job is enqueued at the given time interval. In order for this to work, GoodJob must preserve cron-created job records; these records will be automatically deleted like any other preserved record.
|
616
|
+
Cron-style jobs can be enequeued by any GoodJob process (e.g., CLI or `:async` execution mode) that has `config.good_job.enable_cron` set to `true`. Enabling cron on multiple processes will not enqueue duplicate jobs; GoodJob's cron uses unique indexes to ensure that only a single job is enqueued for a given time interval. In order for this to work, GoodJob must preserve cron-created job records; these records will be automatically deleted like any other preserved record.
|
617
617
|
|
618
618
|
Cron-format is parsed by the [`fugit`](https://github.com/floraison/fugit) gem, which has support for seconds-level resolution (e.g. `* * * * * *`) and natural language parsing (e.g. `every second`).
|
619
619
|
|
@@ -622,8 +622,8 @@ If you use the [Dashboard](#dashboard) the scheduled tasks can be viewed in the
|
|
622
622
|
```ruby
|
623
623
|
# config/environments/application.rb or a specific environment e.g. production.rb
|
624
624
|
|
625
|
-
# Enable cron in this process
|
626
|
-
config.good_job.enable_cron =
|
625
|
+
# Enable cron enqueuing in this process
|
626
|
+
config.good_job.enable_cron = true
|
627
627
|
|
628
628
|
# Configure cron with a hash that has a unique key for each recurring job
|
629
629
|
config.good_job.cron = {
|
@@ -890,7 +890,7 @@ To upgrade:
|
|
890
890
|
|
891
891
|
Notable changes:
|
892
892
|
|
893
|
-
- Only supports Rails 6.1+, CRuby 3.0+ and JRuby 9.4
|
893
|
+
- Only supports Rails 6.1+, CRuby 3.0+ and JRuby 9.4+. Rails 6.0 is no longer supported. CRuby 2.6 and 2.7 are no longer supported. JRuby 9.3 is no longer supported.
|
894
894
|
- Changes job `priority` to give smaller numbers higher priority (default: `0`), in accordance with Active Job's definition of priority.
|
895
895
|
- Enqueues and executes jobs via the `GoodJob::Job` model instead of `GoodJob::Execution`
|
896
896
|
- Setting `config.good_job.cleanup_interval_jobs`, `GOOD_JOB_CLEANUP_INTERVAL_JOBS`, `config.good_job.cleanup_interval_seconds`, or `GOOD_JOB_CLEANUP_INTERVAL_SECONDS` to `nil` or `""` no longer disables count- or time-based cleanups. Set to `false` to disable, or `-1` to run a cleanup after every job execution.
|
@@ -15,9 +15,9 @@ module GoodJob
|
|
15
15
|
discarded: 5,
|
16
16
|
}
|
17
17
|
if Gem::Version.new(Rails.version) >= Gem::Version.new('7.1.0.a')
|
18
|
-
enum :error_event, error_event_enum, validate: { allow_nil: true }
|
18
|
+
enum :error_event, error_event_enum, validate: { allow_nil: true }, scopes: false
|
19
19
|
else
|
20
|
-
enum error_event: error_event_enum
|
20
|
+
enum error_event: error_event_enum, _scopes: false
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
@@ -92,10 +92,12 @@ module GoodJob
|
|
92
92
|
if record.new_record?
|
93
93
|
record.save!
|
94
94
|
else
|
95
|
-
record.
|
96
|
-
record.
|
97
|
-
|
98
|
-
|
95
|
+
record.transaction do
|
96
|
+
record.with_advisory_lock(function: "pg_advisory_xact_lock") do
|
97
|
+
record.enqueued_at_will_change!
|
98
|
+
record.finished_at_will_change!
|
99
|
+
record.update!(enqueued_at: nil, finished_at: nil)
|
100
|
+
end
|
99
101
|
end
|
100
102
|
end
|
101
103
|
|
@@ -135,6 +137,21 @@ module GoodJob
|
|
135
137
|
buffer.active_jobs
|
136
138
|
end
|
137
139
|
|
140
|
+
def retry
|
141
|
+
Rails.application.executor.wrap do
|
142
|
+
buffer = GoodJob::Adapter::InlineBuffer.capture do
|
143
|
+
record.transaction do
|
144
|
+
record.with_advisory_lock(function: "pg_advisory_xact_lock") do
|
145
|
+
record.update!(discarded_at: nil, finished_at: nil)
|
146
|
+
record.jobs.discarded.each(&:retry_job)
|
147
|
+
record._continue_discard_or_finish(lock: false)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
buffer.call
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
138
155
|
def active_jobs
|
139
156
|
record.jobs.map(&:active_job)
|
140
157
|
end
|
@@ -84,11 +84,7 @@ module GoodJob
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
if Rails.gem_version < Gem::Version.new('
|
88
|
-
# serialize does not yet take a default value, must set via Attributes API
|
89
|
-
attribute :serialized_properties, :json, default: -> { {} }
|
90
|
-
serialize :serialized_properties, PropertySerializer
|
91
|
-
elsif Rails.gem_version < Gem::Version.new('7.1.0.alpha')
|
87
|
+
if Rails.gem_version < Gem::Version.new('7.1.0.alpha')
|
92
88
|
serialize :serialized_properties, PropertySerializer, default: -> { {} }
|
93
89
|
else
|
94
90
|
serialize :serialized_properties, coder: PropertySerializer, default: -> { {} }
|
data/app/models/good_job/job.rb
CHANGED
@@ -57,9 +57,9 @@ module GoodJob
|
|
57
57
|
# Execution errored, will run in the future
|
58
58
|
scope :retried, -> { where(finished_at: nil).where(coalesce_scheduled_at_created_at.gt(bind_value('coalesce', Time.current, ActiveRecord::Type::DateTime))).where(params_execution_count.gt(1)) }
|
59
59
|
# Immediate/Scheduled time to run has passed, waiting for an available thread run
|
60
|
-
scope :queued, -> { where(performed_at: nil, finished_at: nil).where(coalesce_scheduled_at_created_at.lteq(bind_value('coalesce', Time.current, ActiveRecord::Type::DateTime)))
|
60
|
+
scope :queued, -> { where(performed_at: nil, finished_at: nil).where(coalesce_scheduled_at_created_at.lteq(bind_value('coalesce', Time.current, ActiveRecord::Type::DateTime))) }
|
61
61
|
# Advisory locked and executing
|
62
|
-
scope :running, -> { where.not(performed_at: nil).where(finished_at: nil)
|
62
|
+
scope :running, -> { where.not(performed_at: nil).where(finished_at: nil) }
|
63
63
|
# Finished executing (succeeded or discarded)
|
64
64
|
scope :finished, -> { where.not(finished_at: nil) }
|
65
65
|
# Completed executing successfully
|
@@ -99,13 +99,7 @@ module GoodJob
|
|
99
99
|
# @!method priority_ordered
|
100
100
|
# @!scope class
|
101
101
|
# @return [ActiveRecord::Relation]
|
102
|
-
scope :priority_ordered, (
|
103
|
-
if GoodJob.configuration.smaller_number_is_higher_priority
|
104
|
-
order('priority ASC NULLS LAST')
|
105
|
-
else
|
106
|
-
order('priority DESC NULLS LAST')
|
107
|
-
end
|
108
|
-
end)
|
102
|
+
scope :priority_ordered, -> { order('priority ASC NULLS LAST') }
|
109
103
|
|
110
104
|
# Order jobs by created_at, for first-in first-out
|
111
105
|
# @!method creation_ordered
|
@@ -146,24 +140,6 @@ module GoodJob
|
|
146
140
|
# @return [ActiveRecord::Relation]
|
147
141
|
scope :schedule_ordered, -> { order(coalesce_scheduled_at_created_at.asc) }
|
148
142
|
|
149
|
-
# Get completed jobs before the given timestamp. If no timestamp is
|
150
|
-
# provided, get *all* completed jobs. By default, GoodJob
|
151
|
-
# destroys jobs after they're completed, meaning this returns no jobs.
|
152
|
-
# However, if you have changed {GoodJob.preserve_job_records}, this may
|
153
|
-
# find completed Jobs.
|
154
|
-
# @!method finished(timestamp = nil)
|
155
|
-
# @!scope class
|
156
|
-
# @param timestamp (Float)
|
157
|
-
# Get jobs that finished before this time (in epoch time).
|
158
|
-
# @return [ActiveRecord::Relation]
|
159
|
-
scope :finished, ->(timestamp = nil) { timestamp ? where(arel_table['finished_at'].lteq(bind_value('finished_at', timestamp, ActiveRecord::Type::DateTime))) : where.not(finished_at: nil) }
|
160
|
-
|
161
|
-
# Get Jobs that started but not finished yet.
|
162
|
-
# @!method running
|
163
|
-
# @!scope class
|
164
|
-
# @return [ActiveRecord::Relation]
|
165
|
-
scope :running, -> { where.not(performed_at: nil).where(finished_at: nil) }
|
166
|
-
|
167
143
|
# Get Jobs on queues that match the given queue string.
|
168
144
|
# @!method queue_string(string)
|
169
145
|
# @!scope class
|
@@ -20,9 +20,9 @@ module GoodJob # :nodoc:
|
|
20
20
|
advisory: 0,
|
21
21
|
}
|
22
22
|
if Gem::Version.new(Rails.version) >= Gem::Version.new('7.1.0.a')
|
23
|
-
enum :lock_type, lock_type_enum, validate: { allow_nil: true }
|
23
|
+
enum :lock_type, lock_type_enum, validate: { allow_nil: true }, scopes: false
|
24
24
|
else
|
25
|
-
enum lock_type: lock_type_enum
|
25
|
+
enum lock_type: lock_type_enum, _scopes: false
|
26
26
|
end
|
27
27
|
|
28
28
|
has_many :locked_jobs, class_name: "GoodJob::Job", foreign_key: :locked_by_id, inverse_of: :locked_by_process, dependent: nil
|
@@ -56,7 +56,7 @@ module GoodJob # :nodoc:
|
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
59
|
-
def self.
|
59
|
+
def self.find_or_create_record(id:, with_advisory_lock: false)
|
60
60
|
attributes = {
|
61
61
|
id: id,
|
62
62
|
state: process_state,
|
@@ -66,6 +66,17 @@ module GoodJob # :nodoc:
|
|
66
66
|
attributes[:lock_type] = :advisory
|
67
67
|
end
|
68
68
|
create!(attributes)
|
69
|
+
rescue ActiveRecord::RecordNotUnique
|
70
|
+
find_by(id: id).tap do |existing_record|
|
71
|
+
next unless existing_record
|
72
|
+
|
73
|
+
if with_advisory_lock
|
74
|
+
existing_record.advisory_lock!
|
75
|
+
existing_record.update(lock_type: :advisory, state: process_state, updated_at: Time.current)
|
76
|
+
else
|
77
|
+
existing_record.update(lock_type: nil, state: process_state, updated_at: Time.current)
|
78
|
+
end
|
79
|
+
end
|
69
80
|
end
|
70
81
|
|
71
82
|
def self.process_state
|
@@ -59,6 +59,12 @@
|
|
59
59
|
<%= batch.jobs.size %>
|
60
60
|
</div>
|
61
61
|
<div class="col text-end">
|
62
|
+
<% if batch.discarded? %>
|
63
|
+
<%= link_to retry_batch_path(batch), method: :put, class: "btn btn-sm btn-outline-primary", title: t("good_job.batches.actions.retry"), data: { confirm: t("good_job.batches.actions.confirm_retry") } do %>
|
64
|
+
<%= render_icon "arrow_clockwise" %>
|
65
|
+
<%= t "good_job.batches.actions.retry" %>
|
66
|
+
<% end %>
|
67
|
+
<% end %>
|
62
68
|
<%= tag.button type: "button", class: "btn btn-sm text-muted", role: "button",
|
63
69
|
title: t("good_job.actions.inspect"),
|
64
70
|
data: { bs_toggle: "collapse", bs_target: "##{dom_id(batch, 'properties')}" },
|
@@ -10,6 +10,14 @@
|
|
10
10
|
<h2 class="h5 mt-2"><%= @batch.description %></h2>
|
11
11
|
</nav>
|
12
12
|
</div>
|
13
|
+
<div class="col text-end">
|
14
|
+
<% if @batch.discarded? %>
|
15
|
+
<%= button_to retry_batch_path(@batch), method: :put, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: t("good_job.batches.actions.retry") }, title: t("good_job.batches.actions.retry"), data: { confirm: t("good_job.batches.actions.confirm_retry") } do %>
|
16
|
+
<%= render_icon "arrow_clockwise" %>
|
17
|
+
<%= t "good_job.actions.retry" %>
|
18
|
+
<% end %>
|
19
|
+
<% end %>
|
20
|
+
</div>
|
13
21
|
</div>
|
14
22
|
</div>
|
15
23
|
</div>
|
data/config/locales/de.yml
CHANGED
@@ -9,6 +9,9 @@ de:
|
|
9
9
|
reschedule: Umplanen
|
10
10
|
retry: Wiederholen
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Bist du sicher, dass du diesen Batch wiederholen willst?
|
14
|
+
retry: Batch wiederholen
|
12
15
|
index:
|
13
16
|
older_batches: Ältere Batches
|
14
17
|
title: Batches
|
@@ -24,6 +27,8 @@ de:
|
|
24
27
|
retry: Job wiederholen
|
25
28
|
title: Aktionen
|
26
29
|
no_jobs_found: Keine Jobs gefunden.
|
30
|
+
retry:
|
31
|
+
notice: Batch wurde wiederholt
|
27
32
|
show:
|
28
33
|
attributes: Attribute
|
29
34
|
batched_jobs: Batch-Jobs
|
data/config/locales/en.yml
CHANGED
@@ -9,6 +9,9 @@ en:
|
|
9
9
|
reschedule: Reschedule
|
10
10
|
retry: Retry
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Are you sure you want to retry this batch?
|
14
|
+
retry: Retry
|
12
15
|
index:
|
13
16
|
older_batches: Older batches
|
14
17
|
title: Batches
|
@@ -24,6 +27,8 @@ en:
|
|
24
27
|
retry: Retry Job
|
25
28
|
title: Actions
|
26
29
|
no_jobs_found: No jobs found.
|
30
|
+
retry:
|
31
|
+
notice: Batch has been retried
|
27
32
|
show:
|
28
33
|
attributes: Attributes
|
29
34
|
batched_jobs: Batched Jobs
|
data/config/locales/es.yml
CHANGED
@@ -9,6 +9,9 @@ es:
|
|
9
9
|
reschedule: Reprogramar
|
10
10
|
retry: Reintentar
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: "¿Estás seguro que querés reintentar este lote?"
|
14
|
+
retry: Reintentar
|
12
15
|
index:
|
13
16
|
older_batches: Lotes anteriores
|
14
17
|
title: Lotes
|
@@ -24,6 +27,8 @@ es:
|
|
24
27
|
retry: Reintentar tarea
|
25
28
|
title: Acciones
|
26
29
|
no_jobs_found: No hay tareas.
|
30
|
+
retry:
|
31
|
+
notice: El lote ha sido reintentado
|
27
32
|
show:
|
28
33
|
attributes: Atributos
|
29
34
|
batched_jobs: Tareas en lote
|
data/config/locales/fr.yml
CHANGED
@@ -9,6 +9,9 @@ fr:
|
|
9
9
|
reschedule: Reprogrammer
|
10
10
|
retry: Recommencez
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Voulez-vous vraiment réessayer ce lot ?
|
14
|
+
retry: Réessayer
|
12
15
|
index:
|
13
16
|
older_batches: Lots plus anciens
|
14
17
|
title: Lots
|
@@ -24,6 +27,8 @@ fr:
|
|
24
27
|
retry: Réessayer le job
|
25
28
|
title: Actions
|
26
29
|
no_jobs_found: Aucun job trouvé.
|
30
|
+
retry:
|
31
|
+
notice: Le lot a été réessayé
|
27
32
|
show:
|
28
33
|
attributes: Attributs
|
29
34
|
batched_jobs: Jobs groupés
|
data/config/locales/it.yml
CHANGED
@@ -9,6 +9,9 @@ it:
|
|
9
9
|
reschedule: Riprogramma
|
10
10
|
retry: Riprova
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Sei sicuro di voler riprovare questo batch?
|
14
|
+
retry: Riprova
|
12
15
|
index:
|
13
16
|
older_batches: Batch più vecchi
|
14
17
|
title: Batch
|
@@ -24,6 +27,8 @@ it:
|
|
24
27
|
retry: Riprova job
|
25
28
|
title: Azioni
|
26
29
|
no_jobs_found: Nessun job trovato.
|
30
|
+
retry:
|
31
|
+
notice: Il batch è stato riprovato
|
27
32
|
show:
|
28
33
|
attributes: Attributi
|
29
34
|
batched_jobs: Job raggruppati
|
data/config/locales/ja.yml
CHANGED
@@ -9,6 +9,9 @@ ja:
|
|
9
9
|
reschedule: 再スケジュールする
|
10
10
|
retry: 再試行する
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: このバッチを再試行してもよろしいですか?
|
14
|
+
retry: バッチを再試行する
|
12
15
|
index:
|
13
16
|
older_batches: より古いバッチ
|
14
17
|
title: バッチ
|
@@ -24,6 +27,8 @@ ja:
|
|
24
27
|
retry: ジョブを再試行する
|
25
28
|
title: アクション
|
26
29
|
no_jobs_found: ジョブが見つかりませんでした。
|
30
|
+
retry:
|
31
|
+
notice: バッチが再試行されました
|
27
32
|
show:
|
28
33
|
attributes: 属性
|
29
34
|
batched_jobs: バッチ処理されたジョブ
|
@@ -122,9 +127,9 @@ ja:
|
|
122
127
|
discard:
|
123
128
|
notice: ジョブが破棄されました
|
124
129
|
executions:
|
125
|
-
application_trace:
|
126
|
-
full_trace:
|
127
|
-
in_queue:
|
130
|
+
application_trace: アプリケーショントレース
|
131
|
+
full_trace: フルトレース
|
132
|
+
in_queue: キュー内
|
128
133
|
runtime: 実行時間
|
129
134
|
title: 実行
|
130
135
|
force_discard:
|
@@ -198,8 +203,8 @@ ja:
|
|
198
203
|
index:
|
199
204
|
average_duration: 平均所要時間
|
200
205
|
chart_title: ジョブの総実行時間(秒
|
201
|
-
executions:
|
202
|
-
job_class:
|
206
|
+
executions: 実行
|
207
|
+
job_class: ジョブクラス
|
203
208
|
maximum_duration: 最大持続時間
|
204
209
|
minimum_duration: 最小期間
|
205
210
|
title: パフォーマンス
|
data/config/locales/ko.yml
CHANGED
@@ -9,6 +9,9 @@ ko:
|
|
9
9
|
reschedule: 재예약하기
|
10
10
|
retry: 다시 시도하기
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: 이 배치를 다시 시도하시겠습니까?
|
14
|
+
retry: 배치 다시 시도
|
12
15
|
index:
|
13
16
|
older_batches: 더 오래된 배치
|
14
17
|
title: 배치
|
@@ -24,6 +27,8 @@ ko:
|
|
24
27
|
retry: 작업 다시 시도
|
25
28
|
title: 작업 액션
|
26
29
|
no_jobs_found: 작업이 없습니다.
|
30
|
+
retry:
|
31
|
+
notice: 배치가 다시 시도되었습니다.
|
27
32
|
show:
|
28
33
|
attributes: 속성
|
29
34
|
batched_jobs: 배치된 작업
|
@@ -122,8 +127,8 @@ ko:
|
|
122
127
|
discard:
|
123
128
|
notice: 작업이 폐기되었습니다.
|
124
129
|
executions:
|
125
|
-
application_trace:
|
126
|
-
full_trace:
|
130
|
+
application_trace: 애플리케이션 추적
|
131
|
+
full_trace: 전체 추적
|
127
132
|
in_queue: 대기 중
|
128
133
|
runtime: 실행 시간
|
129
134
|
title: 실행
|
@@ -198,8 +203,8 @@ ko:
|
|
198
203
|
index:
|
199
204
|
average_duration: 평균 지속 시간
|
200
205
|
chart_title: 총 작업 실행 시간(초)
|
201
|
-
executions:
|
202
|
-
job_class:
|
206
|
+
executions: 실행
|
207
|
+
job_class: 작업 클래스
|
203
208
|
maximum_duration: 최대 기간
|
204
209
|
minimum_duration: 최소 기간
|
205
210
|
title: 성능
|
data/config/locales/nl.yml
CHANGED
@@ -9,6 +9,9 @@ nl:
|
|
9
9
|
reschedule: Opnieuw plannen
|
10
10
|
retry: Opnieuw proberen
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Weet je zeker dat je deze batch opnieuw wilt proberen?
|
14
|
+
retry: Batch opnieuw proberen
|
12
15
|
index:
|
13
16
|
older_batches: Oudere partijen
|
14
17
|
title: Partijen
|
@@ -24,6 +27,8 @@ nl:
|
|
24
27
|
retry: Taak opnieuw
|
25
28
|
title: Acties
|
26
29
|
no_jobs_found: Geen vacatures gevonden.
|
30
|
+
retry:
|
31
|
+
notice: Batch is opnieuw geprobeerd
|
27
32
|
show:
|
28
33
|
attributes: attributen
|
29
34
|
batched_jobs: Gegroepeerde banen
|
data/config/locales/pt-BR.yml
CHANGED
@@ -9,6 +9,9 @@ pt-BR:
|
|
9
9
|
reschedule: Reagendar
|
10
10
|
retry: Tentar novamente
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Tem certeza de que deseja tentar novamente este lote?
|
14
|
+
retry: Tentar novamente
|
12
15
|
index:
|
13
16
|
older_batches: Lotes antigos
|
14
17
|
title: Lotes
|
@@ -24,6 +27,8 @@ pt-BR:
|
|
24
27
|
retry: Tentar Tarefa Novamente
|
25
28
|
title: Ações
|
26
29
|
no_jobs_found: Nenhuma tarefa encontrada.
|
30
|
+
retry:
|
31
|
+
notice: O lote foi tentado novamente
|
27
32
|
show:
|
28
33
|
attributes: Atributos
|
29
34
|
batched_jobs: Tarefas em Lote
|
data/config/locales/ru.yml
CHANGED
@@ -9,6 +9,9 @@ ru:
|
|
9
9
|
reschedule: Перенести
|
10
10
|
retry: Повторить попытку
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Вы уверены, что хотите повторить эту группу заданий?
|
14
|
+
retry: Повторить группу заданий
|
12
15
|
index:
|
13
16
|
older_batches: Старые группы заданий
|
14
17
|
title: Группы заданий
|
@@ -24,6 +27,8 @@ ru:
|
|
24
27
|
retry: Повторить задание
|
25
28
|
title: Действия
|
26
29
|
no_jobs_found: Заданий не найдено
|
30
|
+
retry:
|
31
|
+
notice: Группа заданий была повторена
|
27
32
|
show:
|
28
33
|
attributes: Атрибуты
|
29
34
|
batched_jobs: Группы заданий
|
data/config/locales/tr.yml
CHANGED
@@ -9,6 +9,9 @@ tr:
|
|
9
9
|
reschedule: Yeniden planla
|
10
10
|
retry: Tekrar dene
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Bu grubu yeniden denemek istediğinizden emin misiniz?
|
14
|
+
retry: Grubu yeniden dene
|
12
15
|
index:
|
13
16
|
older_batches: Daha eski toplu işlemler
|
14
17
|
title: Toplu İşlemler
|
@@ -24,6 +27,8 @@ tr:
|
|
24
27
|
retry: İşi Tekrar Dene
|
25
28
|
title: İşlemler
|
26
29
|
no_jobs_found: İş bulunamadı.
|
30
|
+
retry:
|
31
|
+
notice: Grup yeniden denendi
|
27
32
|
show:
|
28
33
|
attributes: Özellikler
|
29
34
|
batched_jobs: Toplu İşlenmiş İşler
|
data/config/locales/uk.yml
CHANGED
@@ -9,6 +9,9 @@ uk:
|
|
9
9
|
reschedule: Перепланувати
|
10
10
|
retry: Повторити
|
11
11
|
batches:
|
12
|
+
actions:
|
13
|
+
confirm_retry: Ви впевнені, що хочете повторити цю групу завдань?
|
14
|
+
retry: Повторити групу завдань
|
12
15
|
index:
|
13
16
|
older_batches: Старі пакети
|
14
17
|
title: Пакети
|
@@ -24,6 +27,8 @@ uk:
|
|
24
27
|
retry: Повторити задачу
|
25
28
|
title: Дії
|
26
29
|
no_jobs_found: Задачі не знайдені.
|
30
|
+
retry:
|
31
|
+
notice: Групу завдань було повторено
|
27
32
|
show:
|
28
33
|
attributes: Атрибути
|
29
34
|
batched_jobs: Задачі в пакеті
|
@@ -256,7 +261,7 @@ uk:
|
|
256
261
|
queue_name: Назва черги
|
257
262
|
search: Пошук
|
258
263
|
navbar:
|
259
|
-
batches:
|
264
|
+
batches: Пакети
|
260
265
|
cron_schedules: Cron
|
261
266
|
jobs: Задачі
|
262
267
|
live_poll: Живе Опитування
|
data/config/routes.rb
CHANGED
@@ -19,7 +19,11 @@ GoodJob::Engine.routes.draw do
|
|
19
19
|
get 'jobs/metrics/primary_nav', to: 'metrics#primary_nav', as: :metrics_primary_nav
|
20
20
|
get 'jobs/metrics/job_status', to: 'metrics#job_status', as: :metrics_job_status
|
21
21
|
|
22
|
-
resources :batches, only: %i[index show]
|
22
|
+
resources :batches, only: %i[index show] do
|
23
|
+
member do
|
24
|
+
put :retry
|
25
|
+
end
|
26
|
+
end
|
23
27
|
|
24
28
|
resources :cron_entries, only: %i[index show], param: :cron_key do
|
25
29
|
member do
|
@@ -35,6 +39,6 @@ GoodJob::Engine.routes.draw do
|
|
35
39
|
|
36
40
|
scope :frontend, controller: :frontends, defaults: { version: GoodJob::VERSION.tr(".", "-") } do
|
37
41
|
get "modules/:version/:id", action: :module, as: :frontend_module, constraints: { format: 'js' }
|
38
|
-
get "static/:version/:id", action: :static, as: :frontend_static
|
42
|
+
get "static/:version/:id", action: :static, as: :frontend_static
|
39
43
|
end
|
40
44
|
end
|
@@ -149,8 +149,10 @@ module GoodJob
|
|
149
149
|
.order(Arel.sql("COALESCE(performed_at, scheduled_at, created_at) ASC"))
|
150
150
|
.limit(limit).pluck(:active_job_id)
|
151
151
|
# The current job has already been locked and will appear in the previous query
|
152
|
-
|
153
|
-
|
152
|
+
unless allowed_active_job_ids.include?(job.job_id)
|
153
|
+
exceeded = :limit
|
154
|
+
next
|
155
|
+
end
|
154
156
|
end
|
155
157
|
|
156
158
|
if throttle
|
@@ -165,8 +167,10 @@ module GoodJob
|
|
165
167
|
.limit(throttle_limit)
|
166
168
|
.pluck(:active_job_id)
|
167
169
|
|
168
|
-
|
169
|
-
|
170
|
+
unless allowed_active_job_ids.include?(job.job_id)
|
171
|
+
exceeded = :throttle
|
172
|
+
next
|
173
|
+
end
|
170
174
|
end
|
171
175
|
end
|
172
176
|
|
@@ -57,7 +57,7 @@ module GoodJob # :nodoc:
|
|
57
57
|
if @record
|
58
58
|
@record.refresh_if_stale
|
59
59
|
else
|
60
|
-
@record = GoodJob::Process.
|
60
|
+
@record = GoodJob::Process.find_or_create_record(id: @record_id)
|
61
61
|
create_refresh_task
|
62
62
|
end
|
63
63
|
value = @record&.id
|
@@ -89,7 +89,7 @@ module GoodJob # :nodoc:
|
|
89
89
|
@advisory_locked_connection = WeakRef.new(@record.class.connection)
|
90
90
|
end
|
91
91
|
else
|
92
|
-
@record = GoodJob::Process.
|
92
|
+
@record = GoodJob::Process.find_or_create_record(id: @record_id, with_advisory_lock: true)
|
93
93
|
@advisory_locked_connection = WeakRef.new(@record.class.connection)
|
94
94
|
create_refresh_task
|
95
95
|
end
|
@@ -35,8 +35,6 @@ module GoodJob
|
|
35
35
|
DEFAULT_DASHBOARD_LIVE_POLL_ENABLED = true
|
36
36
|
# Default enqueue_after_transaction_commit
|
37
37
|
DEFAULT_ENQUEUE_AFTER_TRANSACTION_COMMIT = false
|
38
|
-
# Default smaller_number_is_higher_priority
|
39
|
-
DEFAULT_SMALLER_NUMBER_IS_HIGHER_PRIORITY = true
|
40
38
|
|
41
39
|
def self.validate_execution_mode(execution_mode)
|
42
40
|
raise ArgumentError, "GoodJob execution mode must be one of #{EXECUTION_MODES.join(', ')}. It was '#{execution_mode}' which is not valid." unless execution_mode.in?(EXECUTION_MODES)
|
@@ -347,12 +345,6 @@ module GoodJob
|
|
347
345
|
DEFAULT_ENABLE_LISTEN_NOTIFY
|
348
346
|
end
|
349
347
|
|
350
|
-
def smaller_number_is_higher_priority
|
351
|
-
return rails_config[:smaller_number_is_higher_priority] unless rails_config[:smaller_number_is_higher_priority].nil?
|
352
|
-
|
353
|
-
DEFAULT_SMALLER_NUMBER_IS_HIGHER_PRIORITY
|
354
|
-
end
|
355
|
-
|
356
348
|
def dashboard_default_locale
|
357
349
|
rails_config[:dashboard_default_locale] || DEFAULT_DASHBOARD_DEFAULT_LOCALE
|
358
350
|
end
|
@@ -385,6 +377,16 @@ module GoodJob
|
|
385
377
|
end || false
|
386
378
|
end
|
387
379
|
|
380
|
+
# Whether to take an advisory lock on the process record in the notifier reactor.
|
381
|
+
# @return [Boolean]
|
382
|
+
def advisory_lock_heartbeat
|
383
|
+
return options[:advisory_lock_heartbeat] unless options[:advisory_lock_heartbeat].nil?
|
384
|
+
return rails_config[:advisory_lock_heartbeat] unless rails_config[:advisory_lock_heartbeat].nil?
|
385
|
+
return ActiveModel::Type::Boolean.new.cast(env['GOOD_JOB_ADVISORY_LOCK_HEARTBEAT']) unless env['GOOD_JOB_ADVISORY_LOCK_HEARTBEAT'].nil?
|
386
|
+
|
387
|
+
Rails.env.development?
|
388
|
+
end
|
389
|
+
|
388
390
|
private
|
389
391
|
|
390
392
|
def rails_config
|
@@ -14,9 +14,10 @@ module GoodJob # :nodoc:
|
|
14
14
|
|
15
15
|
# Registers the current process.
|
16
16
|
def register_process
|
17
|
+
@advisory_lock_heartbeat = GoodJob.configuration.advisory_lock_heartbeat
|
17
18
|
GoodJob::Process.override_connection(connection) do
|
18
19
|
GoodJob::Process.cleanup
|
19
|
-
@capsule.tracker.register(with_advisory_lock:
|
20
|
+
@capsule.tracker.register(with_advisory_lock: @advisory_lock_heartbeat)
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
@@ -33,7 +34,7 @@ module GoodJob # :nodoc:
|
|
33
34
|
# Deregisters the current process.
|
34
35
|
def deregister_process
|
35
36
|
GoodJob::Process.override_connection(connection) do
|
36
|
-
@capsule.tracker.unregister(with_advisory_lock:
|
37
|
+
@capsule.tracker.unregister(with_advisory_lock: @advisory_lock_heartbeat)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
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: 4.
|
4
|
+
version: 4.2.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: 2024-
|
11
|
+
date: 2024-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|