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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a80a59cedda856949e71696310b0b241e1c48f9959c07275ad6afadf02694db1
4
- data.tar.gz: bd60e75a3f468681f7cdea53d8681b9f04ff66e3ea55aa2430cd514805eff1b9
3
+ metadata.gz: 1d98ed0a03595d8d2a70f2a811296cf01d1b0a4d9ff480d0a480fb91591ecafd
4
+ data.tar.gz: 90307d30a72de7f7af5d33a7d64ec9eaa67bb42fc8e8179e48c96f22a0440b5e
5
5
  SHA512:
6
- metadata.gz: 5da8d6fc72c367dee54984d411cef1c34a5cdf4e1d32b2f80e8e787a02cc159e59e004c02695888da6cf5e2dc940a5bb9e3b2452247a7594390c0df8c31a1e56
7
- data.tar.gz: e3a3821681ec9ee55bd5e364c41d4b0bc43801ad51e144a4910b81bd37d68149d03c507bd09e11520cdab1dcc8dbc5f1283a7c332e50c1c06d3fa28db21e0dfc
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 (successful) and discarded (failed) jobs on the Dashboard, GoodJob must be configured to preserve job records. Preservation is enabled by default._
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
- 'finished' => query.finished.count,
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 'finished'
29
- query = query.finished
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
- finished: "check",
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
- finished: "success",
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 will not execute
12
- # - finished: The job executed successfully
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
- :finished
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 Jobs with given ActiveJob ID
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 Jobs with given class name
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 Jobs that have not yet been completed.
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 Jobs that are not scheduled for a later time than now (i.e. jobs that
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 jobs by priority (highest priority first).
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 jobs by created_at, for first-in first-out
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 jobs for de-queueing
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 jobs in order of queues in array param
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 || result.retried? || (result.unhandled_error && GoodJob.preserve_job_records == :on_unhandled_error)
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
- destroy_job
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, retried: current_thread.error_on_retry.present?)
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, retried: false)
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
@@ -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 :finished, -> { not_discarded.where.not(finished_at: nil) }
61
+ scope :succeeded, -> { finished.where(error: nil) }
60
62
  # Errored but will not be retried
61
- scope :discarded, -> { where.not(finished_at: nil).where.not(error: nil) }
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, :finished, :running]
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 != :finished %>
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, :finished]}", title: "Destroy job", data: { confirm: "Confirm destroy", disable: true } do %>
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, :finished] %>
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
@@ -58,11 +58,11 @@ en:
58
58
  processes: Processes
59
59
  status:
60
60
  discarded: Discarded
61
- finished: Finished
62
61
  queued: Queued
63
62
  retried: Retried
64
63
  running: Running
65
64
  scheduled: Scheduled
65
+ succeeded: Succeeded
66
66
  number:
67
67
  format:
68
68
  delimiter: ","
@@ -58,11 +58,11 @@ es:
58
58
  processes: Procesos
59
59
  status:
60
60
  discarded: Descartado
61
- finished: Acabado
62
61
  queued: Puesto en cola
63
62
  retried: reintentado
64
63
  running: Corriendo
65
64
  scheduled: Programado
65
+ succeeded: Acierto
66
66
  number:
67
67
  format:
68
68
  delimiter: " "
@@ -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: "."
@@ -82,11 +82,11 @@ ru:
82
82
  processes: Процессы
83
83
  status:
84
84
  discarded: Отброшено
85
- finished: Законченный
86
85
  queued: В очереди
87
86
  retried: Повторная попытка
88
87
  running: Бег
89
88
  scheduled: по расписанию
89
+ succeeded: удалось
90
90
  number:
91
91
  format:
92
92
  delimiter: " "
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '3.4.8'
4
+ VERSION = '3.5.1'
5
5
  end
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, Symbol, nil]
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.not_discarded unless include_discarded
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.8
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 00:00:00.000000000 Z
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: '0'
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: '0'
264
+ version: '5.6'
265
265
  - !ruby/object:Gem::Dependency
266
266
  name: rspec-rails
267
267
  requirement: !ruby/object:Gem::Requirement