good_job 3.4.8 → 3.5.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 +22 -0
- data/README.md +1 -1
- data/app/filters/good_job/jobs_filter.rb +3 -3
- data/app/helpers/good_job/application_helper.rb +2 -2
- data/app/models/concerns/good_job/reportable.rb +3 -3
- data/app/models/good_job/execution.rb +11 -20
- data/app/models/good_job/execution_result.rb +1 -5
- data/app/models/good_job/job.rb +23 -5
- data/app/views/good_job/jobs/_table.erb +2 -2
- data/app/views/good_job/jobs/show.html.erb +1 -1
- data/config/locales/en.yml +1 -1
- data/config/locales/es.yml +1 -1
- data/config/locales/nl.yml +1 -1
- data/config/locales/ru.yml +1 -1
- data/lib/good_job/version.rb +1 -1
- data/lib/good_job.rb +2 -2
- metadata +6 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1d98ed0a03595d8d2a70f2a811296cf01d1b0a4d9ff480d0a480fb91591ecafd
|
|
4
|
+
data.tar.gz: 90307d30a72de7f7af5d33a7d64ec9eaa67bb42fc8e8179e48c96f22a0440b5e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 710500b2704938b319863efe46d462296afa19f11177fb7e03f64e3cfa32872b1d1c8e793a58e6561e0f15a36125b4c3485be99edf6d1e2f8d9953da408ecb3b
|
|
7
|
+
data.tar.gz: 6d0ae65d53a40340e846cd393a3936fe6ece5b7f5e2ccfdf17ee99f628f528135af11bb2714ee223f1e800b4ced333acc7616a153774d85d9889a0e17753a162
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [v3.5.1](https://github.com/bensheldon/good_job/tree/v3.5.1) (2022-10-20)
|
|
4
|
+
|
|
5
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.5.0...v3.5.1)
|
|
6
|
+
|
|
7
|
+
**Closed issues:**
|
|
8
|
+
|
|
9
|
+
- Assert cancelled jobs [\#724](https://github.com/bensheldon/good_job/issues/724)
|
|
10
|
+
|
|
11
|
+
**Merged pull requests:**
|
|
12
|
+
|
|
13
|
+
- Revert "When not preserving job records, ensure all prior executions are deleted after successful retry" because some retry patterns stopped working [\#729](https://github.com/bensheldon/good_job/pull/729) ([bensheldon](https://github.com/bensheldon))
|
|
14
|
+
|
|
15
|
+
## [v3.5.0](https://github.com/bensheldon/good_job/tree/v3.5.0) (2022-10-18)
|
|
16
|
+
|
|
17
|
+
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.4.8...v3.5.0)
|
|
18
|
+
|
|
19
|
+
**Merged pull requests:**
|
|
20
|
+
|
|
21
|
+
- Fix flaky test for `Scheduler#cleanup_interval_jobs` [\#723](https://github.com/bensheldon/good_job/pull/723) ([bensheldon](https://github.com/bensheldon))
|
|
22
|
+
- Pin development Puma version until Capybara is compatible [\#722](https://github.com/bensheldon/good_job/pull/722) ([bensheldon](https://github.com/bensheldon))
|
|
23
|
+
- Rename Job status of `finished` to `succeeded`; `finished` now means either `succeeded` or `discarded` [\#721](https://github.com/bensheldon/good_job/pull/721) ([bensheldon](https://github.com/bensheldon))
|
|
24
|
+
|
|
3
25
|
## [v3.4.8](https://github.com/bensheldon/good_job/tree/v3.4.8) (2022-10-11)
|
|
4
26
|
|
|
5
27
|
[Full Changelog](https://github.com/bensheldon/good_job/compare/v3.4.7...v3.4.8)
|
data/README.md
CHANGED
|
@@ -363,7 +363,7 @@ GoodJob includes a Dashboard as a mountable `Rails::Engine`.
|
|
|
363
363
|
end
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
-
_To view finished (
|
|
366
|
+
_To view finished jobs (succeeded and discarded) on the Dashboard, GoodJob must be configured to preserve job records. Preservation is enabled by default._
|
|
367
367
|
|
|
368
368
|
**Troubleshooting the Dashboard:** Some applications are unable to autoload the Goodjob Engine. To work around this, explicitly require the Engine at the top of your `config/application.rb` file, immediately after Rails is required and before Bundler requires the Rails' groups.
|
|
369
369
|
|
|
@@ -8,7 +8,7 @@ module GoodJob
|
|
|
8
8
|
'retried' => query.retried.count,
|
|
9
9
|
'queued' => query.queued.count,
|
|
10
10
|
'running' => query.running.count,
|
|
11
|
-
'
|
|
11
|
+
'succeeded' => query.succeeded.count,
|
|
12
12
|
'discarded' => query.discarded.count,
|
|
13
13
|
}
|
|
14
14
|
end
|
|
@@ -25,8 +25,8 @@ module GoodJob
|
|
|
25
25
|
case filter_params[:state]
|
|
26
26
|
when 'discarded'
|
|
27
27
|
query = query.discarded
|
|
28
|
-
when '
|
|
29
|
-
query = query.
|
|
28
|
+
when 'succeeded'
|
|
29
|
+
query = query.succeeded
|
|
30
30
|
when 'retried'
|
|
31
31
|
query = query.retried
|
|
32
32
|
when 'scheduled'
|
|
@@ -24,7 +24,7 @@ module GoodJob
|
|
|
24
24
|
|
|
25
25
|
STATUS_ICONS = {
|
|
26
26
|
discarded: "exclamation",
|
|
27
|
-
|
|
27
|
+
succeeded: "check",
|
|
28
28
|
queued: "dash_circle",
|
|
29
29
|
retried: "arrow_clockwise",
|
|
30
30
|
running: "play",
|
|
@@ -33,7 +33,7 @@ module GoodJob
|
|
|
33
33
|
|
|
34
34
|
STATUS_COLOR = {
|
|
35
35
|
discarded: "danger",
|
|
36
|
-
|
|
36
|
+
succeeded: "success",
|
|
37
37
|
queued: "secondary",
|
|
38
38
|
retried: "warning",
|
|
39
39
|
running: "primary",
|
|
@@ -8,8 +8,8 @@ module GoodJob
|
|
|
8
8
|
# - retried: The job previously errored on execution and will be re-executed in the future.
|
|
9
9
|
# 2. The job is being executed
|
|
10
10
|
# - running: the job is actively being executed by an execution thread
|
|
11
|
-
# 3. The job
|
|
12
|
-
# -
|
|
11
|
+
# 3. The job has finished
|
|
12
|
+
# - succeeded: The job executed successfully
|
|
13
13
|
# - discarded: The job previously errored on execution and will not be re-executed in the future.
|
|
14
14
|
#
|
|
15
15
|
# @return [Symbol]
|
|
@@ -20,7 +20,7 @@ module GoodJob
|
|
|
20
20
|
elsif error.present? && retried_good_job_id.nil?
|
|
21
21
|
:discarded
|
|
22
22
|
else
|
|
23
|
-
:
|
|
23
|
+
:succeeded
|
|
24
24
|
end
|
|
25
25
|
elsif (scheduled_at || created_at) > DateTime.current
|
|
26
26
|
if serialized_params.fetch('executions', 0) > 1
|
|
@@ -66,9 +66,8 @@ module GoodJob
|
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
belongs_to :job, class_name: 'GoodJob::Job', foreign_key: 'active_job_id', primary_key: 'active_job_id', optional: true, inverse_of: :executions
|
|
69
|
-
after_destroy -> { self.class.active_job_id(active_job_id).delete_all }, if: -> { @_destroy_job }
|
|
70
69
|
|
|
71
|
-
# Get
|
|
70
|
+
# Get executions with given ActiveJob ID
|
|
72
71
|
# @!method active_job_id
|
|
73
72
|
# @!scope class
|
|
74
73
|
# @param active_job_id [String]
|
|
@@ -76,7 +75,7 @@ module GoodJob
|
|
|
76
75
|
# @return [ActiveRecord::Relation]
|
|
77
76
|
scope :active_job_id, ->(active_job_id) { where(active_job_id: active_job_id) }
|
|
78
77
|
|
|
79
|
-
# Get
|
|
78
|
+
# Get executions with given class name
|
|
80
79
|
# @!method job_class
|
|
81
80
|
# @!scope class
|
|
82
81
|
# @param string [String]
|
|
@@ -84,32 +83,32 @@ module GoodJob
|
|
|
84
83
|
# @return [ActiveRecord::Relation]
|
|
85
84
|
scope :job_class, ->(job_class) { where("serialized_params->>'job_class' = ?", job_class) }
|
|
86
85
|
|
|
87
|
-
# Get
|
|
86
|
+
# Get executions that have not yet finished (succeeded or discarded).
|
|
88
87
|
# @!method unfinished
|
|
89
88
|
# @!scope class
|
|
90
89
|
# @return [ActiveRecord::Relation]
|
|
91
90
|
scope :unfinished, -> { where(finished_at: nil) }
|
|
92
91
|
|
|
93
|
-
# Get
|
|
92
|
+
# Get executions that are not scheduled for a later time than now (i.e. jobs that
|
|
94
93
|
# are not scheduled or scheduled for earlier than the current time).
|
|
95
94
|
# @!method only_scheduled
|
|
96
95
|
# @!scope class
|
|
97
96
|
# @return [ActiveRecord::Relation]
|
|
98
97
|
scope :only_scheduled, -> { where(arel_table['scheduled_at'].lteq(Time.current)).or(where(scheduled_at: nil)) }
|
|
99
98
|
|
|
100
|
-
# Order
|
|
99
|
+
# Order executions by priority (highest priority first).
|
|
101
100
|
# @!method priority_ordered
|
|
102
101
|
# @!scope class
|
|
103
102
|
# @return [ActiveRecord::Relation]
|
|
104
103
|
scope :priority_ordered, -> { order('priority DESC NULLS LAST') }
|
|
105
104
|
|
|
106
|
-
# Order
|
|
105
|
+
# Order executions by created_at, for first-in first-out
|
|
107
106
|
# @!method creation_ordered
|
|
108
107
|
# @!scope class
|
|
109
108
|
# @return [ActiveRecord:Relation]
|
|
110
109
|
scope :creation_ordered, -> { order('created_at ASC') }
|
|
111
110
|
|
|
112
|
-
# Order
|
|
111
|
+
# Order executions for de-queueing
|
|
113
112
|
# @!method dequeueing_ordered
|
|
114
113
|
# @!scope class
|
|
115
114
|
# @param parsed_queues [Hash]
|
|
@@ -124,7 +123,7 @@ module GoodJob
|
|
|
124
123
|
relation
|
|
125
124
|
end)
|
|
126
125
|
|
|
127
|
-
# Order
|
|
126
|
+
# Order executions in order of queues in array param
|
|
128
127
|
# @!method queue_ordered
|
|
129
128
|
# @!scope class
|
|
130
129
|
# @param queues [Array<string] ordered names of queues
|
|
@@ -299,11 +298,11 @@ module GoodJob
|
|
|
299
298
|
|
|
300
299
|
if result.unhandled_error && GoodJob.retry_on_unhandled_error
|
|
301
300
|
save!
|
|
302
|
-
elsif GoodJob.preserve_job_records == true ||
|
|
301
|
+
elsif GoodJob.preserve_job_records == true || (result.unhandled_error && GoodJob.preserve_job_records == :on_unhandled_error)
|
|
303
302
|
self.finished_at = Time.current
|
|
304
303
|
save!
|
|
305
304
|
else
|
|
306
|
-
|
|
305
|
+
destroy!
|
|
307
306
|
end
|
|
308
307
|
|
|
309
308
|
result
|
|
@@ -355,14 +354,6 @@ module GoodJob
|
|
|
355
354
|
(finished_at || Time.zone.now) - performed_at if performed_at
|
|
356
355
|
end
|
|
357
356
|
|
|
358
|
-
# Destroys this execution and all executions within the same job
|
|
359
|
-
def destroy_job
|
|
360
|
-
@_destroy_job = true
|
|
361
|
-
destroy!
|
|
362
|
-
ensure
|
|
363
|
-
@_destroy_job = false
|
|
364
|
-
end
|
|
365
|
-
|
|
366
357
|
private
|
|
367
358
|
|
|
368
359
|
def active_job_data
|
|
@@ -388,7 +379,7 @@ module GoodJob
|
|
|
388
379
|
end
|
|
389
380
|
handled_error ||= current_thread.error_on_retry || current_thread.error_on_discard
|
|
390
381
|
|
|
391
|
-
ExecutionResult.new(value: value, handled_error: handled_error
|
|
382
|
+
ExecutionResult.new(value: value, handled_error: handled_error)
|
|
392
383
|
rescue StandardError => e
|
|
393
384
|
ExecutionResult.new(value: nil, unhandled_error: e)
|
|
394
385
|
end
|
|
@@ -8,18 +8,14 @@ module GoodJob
|
|
|
8
8
|
attr_reader :handled_error
|
|
9
9
|
# @return [Exception, nil]
|
|
10
10
|
attr_reader :unhandled_error
|
|
11
|
-
# @return [Exception, nil]
|
|
12
|
-
attr_reader :retried
|
|
13
|
-
alias retried? retried
|
|
14
11
|
|
|
15
12
|
# @param value [Object, nil]
|
|
16
13
|
# @param handled_error [Exception, nil]
|
|
17
14
|
# @param unhandled_error [Exception, nil]
|
|
18
|
-
def initialize(value:, handled_error: nil, unhandled_error: nil
|
|
15
|
+
def initialize(value:, handled_error: nil, unhandled_error: nil)
|
|
19
16
|
@value = value
|
|
20
17
|
@handled_error = handled_error
|
|
21
18
|
@unhandled_error = unhandled_error
|
|
22
|
-
@retried = retried
|
|
23
19
|
end
|
|
24
20
|
end
|
|
25
21
|
end
|
data/app/models/good_job/job.rb
CHANGED
|
@@ -55,12 +55,12 @@ module GoodJob
|
|
|
55
55
|
scope :queued, -> { where(finished_at: nil).where('COALESCE(scheduled_at, created_at) <= ?', DateTime.current).joins_advisory_locks.where(pg_locks: { locktype: nil }) }
|
|
56
56
|
# Advisory locked and executing
|
|
57
57
|
scope :running, -> { where(finished_at: nil).joins_advisory_locks.where.not(pg_locks: { locktype: nil }) }
|
|
58
|
+
# Finished executing (succeeded or discarded)
|
|
59
|
+
scope :finished, -> { where.not(finished_at: nil).where(retried_good_job_id: nil) }
|
|
58
60
|
# Completed executing successfully
|
|
59
|
-
scope :
|
|
61
|
+
scope :succeeded, -> { finished.where(error: nil) }
|
|
60
62
|
# Errored but will not be retried
|
|
61
|
-
scope :discarded, -> {
|
|
62
|
-
# Not errored
|
|
63
|
-
scope :not_discarded, -> { where(error: nil) }
|
|
63
|
+
scope :discarded, -> { finished.where.not(error: nil) }
|
|
64
64
|
|
|
65
65
|
# The job's ActiveJob UUID
|
|
66
66
|
# @return [String]
|
|
@@ -115,7 +115,7 @@ module GoodJob
|
|
|
115
115
|
aj_count = serialized_params.fetch('executions', 0)
|
|
116
116
|
# The execution count within serialized_params is not updated
|
|
117
117
|
# once the underlying execution has been executed.
|
|
118
|
-
if status.in? [:discarded, :
|
|
118
|
+
if status.in? [:discarded, :succeeded, :running]
|
|
119
119
|
aj_count + 1
|
|
120
120
|
else
|
|
121
121
|
aj_count
|
|
@@ -154,6 +154,24 @@ module GoodJob
|
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
|
|
157
|
+
# Tests whether the job has finished (succeeded or discarded).
|
|
158
|
+
# @return [Boolean]
|
|
159
|
+
def finished?
|
|
160
|
+
finished_at.present? && retried_good_job_id.nil?
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Tests whether the job has finished but with an error.
|
|
164
|
+
# @return [Boolean]
|
|
165
|
+
def discarded?
|
|
166
|
+
finished? && error.present?
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Tests whether the job has finished without error
|
|
170
|
+
# @return [Boolean]
|
|
171
|
+
def succeeded?
|
|
172
|
+
finished? && !discarded?
|
|
173
|
+
end
|
|
174
|
+
|
|
157
175
|
# Retry a job that has errored and been discarded.
|
|
158
176
|
# This action will create a new {Execution} record for the job.
|
|
159
177
|
# @return [ActiveJob::Base]
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
<span class="font-monospace fw-bold"><%= job.priority %></span>
|
|
76
76
|
</div>
|
|
77
77
|
<div class="col-1 text-center">
|
|
78
|
-
<% if job.executions_count > 0 && job.status != :
|
|
78
|
+
<% if job.executions_count > 0 && job.status != :succeeded %>
|
|
79
79
|
<%= tag.span job.executions_count, class: "badge rounded-pill bg-danger", data: {
|
|
80
80
|
bs_toggle: "popover",
|
|
81
81
|
bs_trigger: "hover focus click",
|
|
@@ -118,7 +118,7 @@
|
|
|
118
118
|
<% end %>
|
|
119
119
|
</li>
|
|
120
120
|
<li>
|
|
121
|
-
<%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :
|
|
121
|
+
<%= link_to job_path(job.id), method: :delete, class: "dropdown-item #{'disabled' unless job.status.in? [:discarded, :succeeded]}", title: "Destroy job", data: { confirm: "Confirm destroy", disable: true } do %>
|
|
122
122
|
<%= render_icon "trash" %>
|
|
123
123
|
Destroy
|
|
124
124
|
<% end %>
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
<% end %>
|
|
48
48
|
<% end %>
|
|
49
49
|
|
|
50
|
-
<% if @job.status.in? [:discarded, :
|
|
50
|
+
<% if @job.status.in? [:discarded, :succeeded] %>
|
|
51
51
|
<%= button_to job_path(@job.id), method: :delete, class: "btn btn-sm btn-outline-primary", form_class: "d-inline-block", aria: { label: "Destroy job" }, title: "Destroy job", data: { confirm: "Confirm destroy" } do %>
|
|
52
52
|
<%= render_icon "trash" %>
|
|
53
53
|
Destroy
|
data/config/locales/en.yml
CHANGED
data/config/locales/es.yml
CHANGED
data/config/locales/nl.yml
CHANGED
|
@@ -58,11 +58,11 @@ nl:
|
|
|
58
58
|
processes: Processen
|
|
59
59
|
status:
|
|
60
60
|
discarded: weggegooid
|
|
61
|
-
finished: Afgewerkt
|
|
62
61
|
queued: In de wachtrij
|
|
63
62
|
retried: Opnieuw geprobeerd
|
|
64
63
|
running: Rennen
|
|
65
64
|
scheduled: Gepland
|
|
65
|
+
succeeded: Geslaagd
|
|
66
66
|
number:
|
|
67
67
|
format:
|
|
68
68
|
delimiter: "."
|
data/config/locales/ru.yml
CHANGED
data/lib/good_job/version.rb
CHANGED
data/lib/good_job.rb
CHANGED
|
@@ -57,7 +57,7 @@ module GoodJob
|
|
|
57
57
|
# By default, GoodJob deletes job records after the job is completed successfully.
|
|
58
58
|
# If you want to preserve jobs for latter inspection, set this to +true+.
|
|
59
59
|
# If you want to preserve only jobs that finished with error for latter inspection, set this to +:on_unhandled_error+.
|
|
60
|
-
# @return [Boolean,
|
|
60
|
+
# @return [Boolean, nil]
|
|
61
61
|
mattr_accessor :preserve_job_records, default: true
|
|
62
62
|
|
|
63
63
|
# @!attribute [rw] retry_on_unhandled_error
|
|
@@ -157,7 +157,7 @@ module GoodJob
|
|
|
157
157
|
|
|
158
158
|
ActiveSupport::Notifications.instrument("cleanup_preserved_jobs.good_job", { older_than: older_than, timestamp: timestamp }) do |payload|
|
|
159
159
|
old_jobs = GoodJob::Job.where('finished_at <= ?', timestamp)
|
|
160
|
-
old_jobs = old_jobs.
|
|
160
|
+
old_jobs = old_jobs.succeeded unless include_discarded
|
|
161
161
|
old_jobs_count = old_jobs.count
|
|
162
162
|
|
|
163
163
|
GoodJob::Execution.where(job: old_jobs).delete_all
|
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: 3.
|
|
4
|
+
version: 3.5.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: 2022-10-
|
|
11
|
+
date: 2022-10-20 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activejob
|
|
@@ -252,16 +252,16 @@ dependencies:
|
|
|
252
252
|
name: puma
|
|
253
253
|
requirement: !ruby/object:Gem::Requirement
|
|
254
254
|
requirements:
|
|
255
|
-
- - "
|
|
255
|
+
- - "~>"
|
|
256
256
|
- !ruby/object:Gem::Version
|
|
257
|
-
version: '
|
|
257
|
+
version: '5.6'
|
|
258
258
|
type: :development
|
|
259
259
|
prerelease: false
|
|
260
260
|
version_requirements: !ruby/object:Gem::Requirement
|
|
261
261
|
requirements:
|
|
262
|
-
- - "
|
|
262
|
+
- - "~>"
|
|
263
263
|
- !ruby/object:Gem::Version
|
|
264
|
-
version: '
|
|
264
|
+
version: '5.6'
|
|
265
265
|
- !ruby/object:Gem::Dependency
|
|
266
266
|
name: rspec-rails
|
|
267
267
|
requirement: !ruby/object:Gem::Requirement
|