good_job 4.1.1 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/README.md +10 -10
- data/app/controllers/good_job/batches_controller.rb +6 -0
- data/app/models/concerns/good_job/error_events.rb +2 -2
- 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: 6b8f73f25f420a1b95841f757ef3eae435fc19e442f157bae03af0e751d619a2
|
4
|
+
data.tar.gz: e6737d5a487ed8d43c0c9dc078b72c075784cfb00889835e63b8ca2ba8788333
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd113e9ed755d014fdbd324bd7aaf62837e384176412d7eeeb4bf277fbd7ed9cb5eba82a39dc4f1e54f4753e635f8c8076194f45d1de461f92301864081cf08f
|
7
|
+
data.tar.gz: 9e028ead209f0467bfe8e2d323ebfe812503ef8310a792270604b525f4aeb5429b7857fbf644bfbc600e14593c0545cf0e628f309aabb8276ca34c6f3ae98367
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,35 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v4.2.0](https://github.com/bensheldon/good_job/tree/v4.2.0) (2024-08-16)
|
4
|
+
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v4.1.1...v4.2.0)
|
6
|
+
|
7
|
+
**Implemented enhancements:**
|
8
|
+
|
9
|
+
- Add retry functionality for batches [\#1456](https://github.com/bensheldon/good_job/pull/1456) ([bensheldon](https://github.com/bensheldon))
|
10
|
+
|
11
|
+
**Fixed bugs:**
|
12
|
+
|
13
|
+
- respect perform\_throttle even if perform\_limit is provided [\#1470](https://github.com/bensheldon/good_job/pull/1470) ([doits](https://github.com/doits))
|
14
|
+
- Do not use advisory lock on heartbeat in production [\#1451](https://github.com/bensheldon/good_job/pull/1451) ([bensheldon](https://github.com/bensheldon))
|
15
|
+
|
16
|
+
**Closed issues:**
|
17
|
+
|
18
|
+
- `perform_limit` and `perform_throttle` don't work both [\#1469](https://github.com/bensheldon/good_job/issues/1469)
|
19
|
+
- Edge rails changes breaking binding commits [\#1466](https://github.com/bensheldon/good_job/issues/1466)
|
20
|
+
- Dynamic creation of CronEntries [\#1457](https://github.com/bensheldon/good_job/issues/1457)
|
21
|
+
- Batch callback job not enqueued after success of retried job [\#1450](https://github.com/bensheldon/good_job/issues/1450)
|
22
|
+
|
23
|
+
**Merged pull requests:**
|
24
|
+
|
25
|
+
- Update cron documentation to remove confusion about multiple processes [\#1467](https://github.com/bensheldon/good_job/pull/1467) ([bensheldon](https://github.com/bensheldon))
|
26
|
+
- Update compatibility matrix, remove compatibility code [\#1465](https://github.com/bensheldon/good_job/pull/1465) ([Earlopain](https://github.com/Earlopain))
|
27
|
+
- Run tests with warnings enabled [\#1462](https://github.com/bensheldon/good_job/pull/1462) ([Earlopain](https://github.com/Earlopain))
|
28
|
+
- 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))
|
29
|
+
- Fix a few method redefinition warnings [\#1459](https://github.com/bensheldon/good_job/pull/1459) ([Earlopain](https://github.com/Earlopain))
|
30
|
+
- 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))
|
31
|
+
- Remove `smaller_number_is_higher_priority` option from v4 [\#1453](https://github.com/bensheldon/good_job/pull/1453) ([bensheldon](https://github.com/bensheldon))
|
32
|
+
|
3
33
|
## [v4.1.1](https://github.com/bensheldon/good_job/tree/v4.1.1) (2024-07-31)
|
4
34
|
|
5
35
|
[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.0
|
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-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activejob
|