good_job 3.15.12 → 3.15.14

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ba9a6bb5f97a64b3ff00e48501cbebf617372e0983c5f87f14bfe25898625b1
4
- data.tar.gz: 673df26ced6db84ea48e77c736d8969216497034d0c19ba3f32016fd0b915afd
3
+ metadata.gz: b2afabac45c47dd0326312ac0f111aaff7c977cc33baded1c2c0b97b824e1510
4
+ data.tar.gz: 5d36fd716c45bb4874c5431945b5423e0385d1e49bb32b98f36902679f62511b
5
5
  SHA512:
6
- metadata.gz: 9b39c600a8cb22842c8f2aee4b952695fad309fafb522f16f74ad9b21c20a9db4e9ff05ea13647024c1cbbb95438168cd620be89fb766605419de21e876a2ce8
7
- data.tar.gz: 8469a0079df3bd25aa8f8474fa5cffe8a67ad7fa91efa70b7e2ebcba50e5132a1880c004e5e6bca2aa3dc12fe844a7cf4219c443644b86c7dde839833a12ab1f
6
+ metadata.gz: 4459b866f3d1f266b5e587e21f5fae9bb30a3deea54716f35658581adbacd09cefe470ef9f0d04f0b8cda53f330fb3ba20f69d706670353bd2615cb44ad6f38c
7
+ data.tar.gz: d37e446d66085c33665bc0e93b5caff2cd249baa0b3394b337e6023f1d9803faea4622a7ffac96d4817196a10ba0a762db57648846f88bc25d1455928fad8865
data/CHANGELOG.md CHANGED
@@ -1,5 +1,37 @@
1
1
  # Changelog
2
2
 
3
+ ## [v3.15.14](https://github.com/bensheldon/good_job/tree/v3.15.14) (2023-07-03)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.15.13...v3.15.14)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Dashboard error when trying to display 0 running/queued/retried jobs due to missing 'zero' translation [\#990](https://github.com/bensheldon/good_job/issues/990)
10
+
11
+ **Closed issues:**
12
+
13
+ - Persisting ActiveSupport::CurrentAttributes [\#981](https://github.com/bensheldon/good_job/issues/981)
14
+ - uninitialized constant DiscreteExecution [\#962](https://github.com/bensheldon/good_job/issues/962)
15
+ - Hard kill resilience with execution counts [\#922](https://github.com/bensheldon/good_job/issues/922)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - Bump rubocop from 1.53.0 to 1.54.0 [\#994](https://github.com/bensheldon/good_job/pull/994) ([dependabot[bot]](https://github.com/apps/dependabot))
20
+ - Bump rails from 7.0.5 to 7.0.6 [\#993](https://github.com/bensheldon/good_job/pull/993) ([dependabot[bot]](https://github.com/apps/dependabot))
21
+ - Fix CI: Lock traces version for Ruby 2.6 compatible version [\#987](https://github.com/bensheldon/good_job/pull/987) ([bensheldon](https://github.com/bensheldon))
22
+ - Turkish Language support [\#986](https://github.com/bensheldon/good_job/pull/986) ([SemihCag](https://github.com/SemihCag))
23
+ - Add explicit namespace back to `GoodJob::DiscreteExecution` [\#983](https://github.com/bensheldon/good_job/pull/983) ([bensheldon](https://github.com/bensheldon))
24
+ - Add Process heartbeat that is updated inside of Notifier [\#977](https://github.com/bensheldon/good_job/pull/977) ([bensheldon](https://github.com/bensheldon))
25
+ - Use generic error reporter in Readme examples [\#964](https://github.com/bensheldon/good_job/pull/964) ([shouichi](https://github.com/shouichi))
26
+
27
+ ## [v3.15.13](https://github.com/bensheldon/good_job/tree/v3.15.13) (2023-06-14)
28
+
29
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.15.12...v3.15.13)
30
+
31
+ **Fixed bugs:**
32
+
33
+ - Replace uncached table\_exists? with cached table\_exists? [\#979](https://github.com/bensheldon/good_job/pull/979) ([cmcinnes-mdsol](https://github.com/cmcinnes-mdsol))
34
+
3
35
  ## [v3.15.12](https://github.com/bensheldon/good_job/tree/v3.15.12) (2023-06-11)
4
36
 
5
37
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.15.11...v3.15.12)
@@ -35,10 +67,6 @@
35
67
 
36
68
  - Ensure migration warning for `DiscreteExecution` constant is in explicit `GoodJob::` namespace [\#963](https://github.com/bensheldon/good_job/pull/963) ([bensheldon](https://github.com/bensheldon))
37
69
 
38
- **Closed issues:**
39
-
40
- - uninitialized constant DiscreteExecution [\#962](https://github.com/bensheldon/good_job/issues/962)
41
-
42
70
  ## [v3.15.9](https://github.com/bensheldon/good_job/tree/v3.15.9) (2023-05-21)
43
71
 
44
72
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.15.8...v3.15.9)
data/README.md CHANGED
@@ -231,7 +231,7 @@ Rails.application.configure do
231
231
  # Configure options individually...
232
232
  config.good_job.preserve_job_records = true
233
233
  config.good_job.retry_on_unhandled_error = false
234
- config.good_job.on_thread_error = -> (exception) { Sentry.capture_exception(exception) }
234
+ config.good_job.on_thread_error = -> (exception) { Rails.error.report(exception) }
235
235
  config.good_job.execution_mode = :async
236
236
  config.good_job.queues = '*'
237
237
  config.good_job.max_threads = 5
@@ -244,7 +244,7 @@ Rails.application.configure do
244
244
  config.good_job = {
245
245
  preserve_job_records: true,
246
246
  retry_on_unhandled_error: false,
247
- on_thread_error: -> (exception) { Sentry.capture_exception(exception) },
247
+ on_thread_error: -> (exception) { Rails.error.report(exception) },
248
248
  execution_mode: :async,
249
249
  queues: '*',
250
250
  max_threads: 5,
@@ -287,7 +287,7 @@ Available configuration options are:
287
287
  - `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:
288
288
 
289
289
  ```ruby
290
- config.good_job.on_thread_error = -> (exception) { Sentry.capture_exception(exception) }
290
+ config.good_job.on_thread_error = -> (exception) { Rails.error.report(exception) }
291
291
  ```
292
292
 
293
293
  By default, GoodJob configures the following execution modes per environment:
@@ -760,7 +760,7 @@ If errors do reach GoodJob, you can assign a callable to `GoodJob.on_thread_erro
760
760
 
761
761
  ```ruby
762
762
  # config/initializers/good_job.rb
763
- GoodJob.on_thread_error = -> (exception) { Sentry.capture_exception(exception) }
763
+ GoodJob.on_thread_error = -> (exception) { Rails.error.report(exception) }
764
764
  ```
765
765
 
766
766
  #### Retries
@@ -794,13 +794,13 @@ class ApplicationJob < ActiveJob::Base
794
794
  retry_on StandardError, wait: :exponentially_longer, attempts: Float::INFINITY
795
795
 
796
796
  retry_on SpecialError, attempts: 5 do |_job, exception|
797
- Sentry.capture_exception(exception)
797
+ Rails.error.report(exception)
798
798
  end
799
799
 
800
800
  around_perform do |_job, block|
801
801
  block.call
802
802
  rescue StandardError => e
803
- Sentry.capture_exception(e)
803
+ Rails.error.report(e)
804
804
  raise
805
805
  end
806
806
  # ...
@@ -823,7 +823,7 @@ ActionMailer::MailDeliveryJob.retry_on StandardError, wait: :exponentially_longe
823
823
  ActionMailer::MailDeliveryJob.around_perform do |_job, block|
824
824
  block.call
825
825
  rescue StandardError => e
826
- Sentry.capture_exception(e)
826
+ Rails.error.report(e)
827
827
  raise
828
828
  end
829
829
  ```
@@ -35,12 +35,7 @@ module GoodJob
35
35
  end
36
36
 
37
37
  def discrete_support?
38
- if connection.table_exists?(GoodJob::DiscreteExecution.table_name)
39
- true
40
- else
41
- migration_pending_warning!
42
- false
43
- end
38
+ GoodJob::DiscreteExecution.migrated?
44
39
  end
45
40
  end
46
41
 
@@ -21,7 +21,7 @@ module GoodJob
21
21
  # Can be overriden by child class.
22
22
  # @return [Boolean]
23
23
  def self.migrated?
24
- return true if connection.table_exists?(table_name)
24
+ return true if table_exists?
25
25
 
26
26
  migration_pending_warning!
27
27
  false
@@ -7,7 +7,9 @@ module GoodJob # :nodoc:
7
7
  include AssignableConnection
8
8
  include Lockable
9
9
 
10
+ # Interval until the process record being updated
10
11
  STALE_INTERVAL = 30.seconds
12
+ # Interval until the process record is treated as expired
11
13
  EXPIRED_INTERVAL = 5.minutes
12
14
 
13
15
  self.table_name = 'good_job_processes'
@@ -31,20 +33,26 @@ module GoodJob # :nodoc:
31
33
  # UUID that is unique to the current process and changes when forked.
32
34
  # @return [String]
33
35
  def self.current_id
34
- mutex.synchronize do
35
- if _current_id.nil? || _pid != ::Process.pid
36
- self._current_id = SecureRandom.uuid
37
- self._pid = ::Process.pid
38
- end
39
- _current_id
36
+ mutex.synchronize { ns_current_id }
37
+ end
38
+
39
+ def self.ns_current_id
40
+ if _current_id.nil? || _pid != ::Process.pid
41
+ self._current_id = SecureRandom.uuid
42
+ self._pid = ::Process.pid
40
43
  end
44
+ _current_id
41
45
  end
42
46
 
43
47
  # Hash representing metadata about the current process.
44
48
  # @return [Hash]
45
49
  def self.current_state
50
+ mutex.synchronize { ns_current_state }
51
+ end
52
+
53
+ def self.ns_current_state
46
54
  {
47
- id: current_id,
55
+ id: ns_current_id,
48
56
  hostname: Socket.gethostname,
49
57
  pid: ::Process.pid,
50
58
  proctitle: $PROGRAM_NAME,
@@ -63,29 +71,43 @@ module GoodJob # :nodoc:
63
71
  # Registers the current process in the database
64
72
  # @return [GoodJob::Process]
65
73
  def self.register
66
- create(id: current_id, state: current_state, create_with_advisory_lock: true)
67
- rescue ActiveRecord::RecordNotUnique
68
- nil
74
+ mutex.synchronize do
75
+ process_state = ns_current_state
76
+ create(id: process_state[:id], state: process_state, create_with_advisory_lock: true)
77
+ rescue ActiveRecord::RecordNotUnique
78
+ find(ns_current_state[:id])
79
+ end
80
+ end
81
+
82
+ def refresh
83
+ mutex.synchronize do
84
+ reload
85
+ update(state: self.class.ns_current_state, updated_at: Time.current)
86
+ rescue ActiveRecord::RecordNotFound
87
+ false
88
+ end
69
89
  end
70
90
 
71
91
  # Unregisters the instance.
72
92
  def deregister
73
93
  return unless owns_advisory_lock?
74
94
 
75
- destroy!
76
- advisory_unlock
95
+ mutex.synchronize do
96
+ destroy!
97
+ advisory_unlock
98
+ end
77
99
  end
78
100
 
79
101
  def basename
80
102
  File.basename(state["proctitle"])
81
103
  end
82
104
 
83
- def refresh
84
- touch(:updated_at) # rubocop:disable Rails/SkipsModelValidations
85
- end
105
+ def refresh_if_stale(cleanup: false)
106
+ return unless stale?
86
107
 
87
- def refresh_if_stale
88
- refresh if stale?
108
+ result = refresh
109
+ self.class.cleanup if cleanup
110
+ result
89
111
  end
90
112
 
91
113
  def stale?
@@ -11,6 +11,9 @@
11
11
  <div class="col-2 d-flex gap-2">
12
12
  <span><%= t ".started" %></span>
13
13
  </div>
14
+ <div class="col-2 d-flex gap-2">
15
+ <span><%= t ".updated" %></span>
16
+ </div>
14
17
  <div class="col-auto">
15
18
  <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
16
19
  data: { bs_toggle: "collapse", bs_target: ".process-state" },
@@ -42,6 +45,7 @@
42
45
  <% end %>
43
46
  </div>
44
47
  <div class="col-2 small"><%= relative_time(process.created_at) %></div>
48
+ <div class="col-2 small"><%= relative_time(process.updated_at) %></div>
45
49
  <div class="col-auto">
46
50
  <%= tag.button type: "button", class: "btn btn-sm text-muted ms-auto", role: "button",
47
51
  title: t("good_job.actions.inspect"),
@@ -190,6 +190,7 @@ de:
190
190
  schedulers: Planer
191
191
  started: Gestartet
192
192
  title: Prozesse
193
+ updated: Aktualisiert
193
194
  shared:
194
195
  filter:
195
196
  all: Alle
@@ -190,6 +190,7 @@ en:
190
190
  schedulers: Schedulers
191
191
  started: Started
192
192
  title: Processes
193
+ updated: Updated
193
194
  shared:
194
195
  filter:
195
196
  all: All
@@ -190,6 +190,7 @@ es:
190
190
  schedulers: Schedulers
191
191
  started: Iniciado
192
192
  title: Procesos
193
+ updated: Actualizado
193
194
  shared:
194
195
  filter:
195
196
  all: Todas
@@ -190,6 +190,7 @@ fr:
190
190
  schedulers: Schedulers
191
191
  started: Lancé
192
192
  title: Processus
193
+ updated: Mis à jour
193
194
  shared:
194
195
  filter:
195
196
  all: Tous
@@ -190,6 +190,7 @@ ja:
190
190
  schedulers: スケジューラー
191
191
  started: 開始日時
192
192
  title: プロセス
193
+ updated: 更新された
193
194
  shared:
194
195
  filter:
195
196
  all: 全て
@@ -190,6 +190,7 @@ nl:
190
190
  schedulers: Planners
191
191
  started: Begonnen
192
192
  title: Processen
193
+ updated: Bijgewerkt
193
194
  shared:
194
195
  filter:
195
196
  all: Alle
@@ -216,6 +216,7 @@ ru:
216
216
  schedulers: Планировщики
217
217
  started: Начал
218
218
  title: Процессы
219
+ updated: Обновлено
219
220
  shared:
220
221
  filter:
221
222
  all: Все
@@ -0,0 +1,220 @@
1
+ ---
2
+ tr:
3
+ good_job:
4
+ actions:
5
+ destroy: Sil
6
+ discard: İptal Et
7
+ inspect: İncele
8
+ reschedule: Yeniden planla
9
+ retry: Tekrar dene
10
+ batches:
11
+ index:
12
+ older_batches: Daha eski toplu işlemler
13
+ pending_migrations: GoodJob'ın bekleyen veritabanı güncellemeleri bulunuyor.
14
+ title: Toplu İşlemler
15
+ jobs:
16
+ actions:
17
+ confirm_destroy: Bu işi silmek istediğinizden emin misiniz?
18
+ confirm_discard: Bu işi iptal etmek istediğinizden emin misiniz?
19
+ confirm_reschedule: Bu işi yeniden planlamak istediğinizden emin misiniz?
20
+ confirm_retry: Bu işi tekrar denemek istediğinizden emin misiniz?
21
+ destroy: İşi Sil
22
+ discard: İşi İptal Et
23
+ reschedule: İşi Yeniden Planla
24
+ retry: İşi Tekrar Dene
25
+ title: İşlemler
26
+ no_jobs_found: İş bulunamadı.
27
+ show:
28
+ attributes: Özellikler
29
+ batched_jobs: Toplu İşlenmiş İşler
30
+ callback_jobs: Geri Çağırma İşleri
31
+ table:
32
+ no_batches_found: Toplu İşlem bulunamadı.
33
+ cron_entries:
34
+ actions:
35
+ confirm_disable: Bu cron girişini devre dışı bırakmak istediğinizden emin misiniz?
36
+ confirm_enable: Bu cron girişini etkinleştirmek istediğinizden emin misiniz?
37
+ confirm_enqueue: Bu cron girişini hemen kuyruğa eklemek istediğinizden emin misiniz?
38
+ disable: Cron girişini devre dışı bırak
39
+ enable: Cron girişini etkinleştir
40
+ enqueue: Cron girişini hemen kuyruğa ekle
41
+ disable:
42
+ notice: Cron girişi devre dışı bırakıldı.
43
+ enable:
44
+ notice: Cron girişi etkinleştirildi.
45
+ enqueue:
46
+ notice: Cron girişi kuyruğa eklendi.
47
+ index:
48
+ no_cron_schedules_found: Planlanmış Cron bulunamadı.
49
+ title: Cron Planları
50
+ pending_migrations: Bekleyen GoodJob veritabanı güncellemesi var.
51
+ show:
52
+ cron_entry_key: Cron Giriş Anahtarı
53
+ datetime:
54
+ distance_in_words:
55
+ about_x_hours:
56
+ one: yaklaşık 1 saat
57
+ other: yaklaşık %{count} saat
58
+ about_x_months:
59
+ one: yaklaşık 1 ay
60
+ other: yaklaşık %{count} ay
61
+ about_x_years:
62
+ one: yaklaşık 1 yıl
63
+ other: yaklaşık %{count} yıl
64
+ almost_x_years:
65
+ one: neredeyse 1 yıl
66
+ other: neredeyse %{count} yıl
67
+ half_a_minute: yarım dakika
68
+ less_than_x_minutes:
69
+ one: 1 dakikadan az
70
+ other: "%{count} dakikadan az"
71
+ less_than_x_seconds:
72
+ one: 1 saniyeden az
73
+ other: "%{count} saniyeden az"
74
+ over_x_years:
75
+ one: 1 yıldan fazla
76
+ other: "%{count} yıldan fazla"
77
+ x_days:
78
+ one: 1 gün
79
+ other: "%{count} gün"
80
+ x_minutes:
81
+ one: 1 dakika
82
+ other: "%{count} dakika"
83
+ x_months:
84
+ one: 1 ay
85
+ other: "%{count} ay"
86
+ x_seconds:
87
+ one: 1 saniye
88
+ other: "%{count} saniye"
89
+ x_years:
90
+ one: 1 yıl
91
+ other: "%{count} yıl"
92
+ duration:
93
+ hours: "%{hour}sa %{min}d"
94
+ less_than_10_seconds: "%{sec} s"
95
+ milliseconds: "%{ms} ms"
96
+ minutes: "%{min}d %{sec}s"
97
+ seconds: "%{sec}s"
98
+ helpers:
99
+ relative_time:
100
+ future: "%{time} içinde"
101
+ past: "%{time} önce"
102
+ jobs:
103
+ actions:
104
+ confirm_destroy: Bu işi silmek istediğinizden emin misiniz?
105
+ confirm_discard: Bu işi iptal etmek istediğinizden emin misiniz?
106
+ confirm_reschedule: Bu işi yeniden planlamak istediğinizden emin misiniz?
107
+ confirm_retry: Bu işi tekrar denemek istediğinizden emin misiniz?
108
+ destroy: İşi Sil
109
+ discard: İşi İptal Et
110
+ reschedule: İşi Yeniden Planla
111
+ retry: İşi Tekrar Dene
112
+ destroy:
113
+ notice: İş Silindi
114
+ discard:
115
+ notice: İş İptal Edildi
116
+ executions:
117
+ error: Hata
118
+ in_queue: sırada
119
+ runtime: çalışma süresi
120
+ title: İşlemler
121
+ index:
122
+ job_pagination: İş sayfalandırması
123
+ older_jobs: Daha eski işler
124
+ reschedule:
125
+ notice: İş yeniden planlandı
126
+ retry:
127
+ notice: İş tekrar deneniyor
128
+ show:
129
+ jobs: İşler
130
+ table:
131
+ actions:
132
+ apply_to_all:
133
+ one: 1 işe uygula.
134
+ other: "%{count} işe uygula."
135
+ confirm_destroy_all: Seçili işleri silmek istediğinizden emin misiniz?
136
+ confirm_discard_all: Seçili işleri iptal etmek istediğinizden emin misiniz?
137
+ confirm_reschedule_all: Seçili işleri yeniden planlamak istediğinizden emin misiniz?
138
+ confirm_retry_all: Seçili işleri tekrar denemek istediğinizden emin misiniz?
139
+ destroy_all: Tümünü Sil
140
+ discard_all: Tümünü İptal Et
141
+ reschedule_all: Tümünü Yeniden Planla
142
+ retry_all: Tümünü Tekrar Dene
143
+ title: İşlemler
144
+ no_jobs_found: İş bulunamadı.
145
+ toggle_actions: İşlemleri Gizle/Göster
146
+ toggle_all_jobs: Tüm işleri Gizle/Göster
147
+ models:
148
+ batch:
149
+ created: Oluşturuldu
150
+ created_at: Oluşturma zamanı
151
+ discarded: İptal Edildi
152
+ discarded_at: İptal edilme zamanı
153
+ enqueued: Kuyruğa eklendi
154
+ enqueued_at: Kuyruğa ekleme zamanı
155
+ finished: Tamamlandı
156
+ finished_at: Tamamlanma zamanı
157
+ jobs: İşler
158
+ name: İsim
159
+ cron:
160
+ class: Sınıf
161
+ last_run: Son çalıştırma
162
+ next_scheduled: Sonraki planlama
163
+ schedule: Program
164
+ job:
165
+ arguments: Argümanlar
166
+ attempts: Denemeler
167
+ priority: Öncelik
168
+ queue: Kuyruk
169
+ number:
170
+ format:
171
+ delimiter: ","
172
+ separator: "."
173
+ human:
174
+ decimal_units:
175
+ delimiter: ","
176
+ format: "%n%u"
177
+ precision: 3
178
+ separator: "."
179
+ units:
180
+ billion: Milyar
181
+ million: Milyon
182
+ quadrillion: Katrilyon
183
+ thousand: Bin
184
+ trillion: Trilyon
185
+ unit: ''
186
+ processes:
187
+ index:
188
+ no_good_job_processes_found: GoodJob süreci bulunamadı.
189
+ process: Süreç
190
+ schedulers: Planlayıcılar
191
+ started: Başlangıç zamanı
192
+ title: Süreçler
193
+ updated: Güncellenmiş
194
+ shared:
195
+ filter:
196
+ all: Tümü
197
+ all_jobs: Tüm işler
198
+ all_queues: Tüm kuyruklar
199
+ clear: Temizle
200
+ job_name: İş adı
201
+ placeholder: Sınıfa, iş kimliğine, iş parametrelerine ve hata metnine göre ara.
202
+ queue_name: Kuyruk adı
203
+ search: Ara
204
+ footer:
205
+ last_update_html: Son güncelleme <time id="page-updated-at" datetime="%{time}">%{time}</time>
206
+ wording: Unutmayın, siz de iyi bir iş yapıyorsunuz!
207
+ navbar:
208
+ batches: Toplu İşler
209
+ cron_schedules: Cron
210
+ jobs: İşler
211
+ live_poll: Anlık Güncelleme
212
+ name: "GoodJob 👍"
213
+ processes: Süreçler
214
+ status:
215
+ discarded: İptal Edildi
216
+ queued: Sırada
217
+ retried: Tekrar deneniyor
218
+ running: Çalışıyor
219
+ scheduled: Planlandı
220
+ succeeded: Başarılı
@@ -192,6 +192,7 @@ ua:
192
192
  schedulers: Планувальники
193
193
  started: Розпочато
194
194
  title: Процеси
195
+ updated: Оновлено
195
196
  shared:
196
197
  filter:
197
198
  all: Всі
@@ -92,7 +92,7 @@ module GoodJob
92
92
  key = self.class.good_job_concurrency_config[:key]
93
93
  return if key.blank?
94
94
 
95
- key = key.respond_to?(:call) ? instance_exec(&key) : key
95
+ key = instance_exec(&key) if key.respond_to?(:call)
96
96
  raise TypeError, "Concurrency key must be a String; was a #{key.class}" unless VALID_TYPES.any? { |type| key.is_a?(type) }
97
97
 
98
98
  key
@@ -49,7 +49,7 @@ module GoodJob
49
49
  # * +nil+ will trigger a shutdown but not wait for it to complete.
50
50
  # @return [void]
51
51
  def shutdown(timeout: :default)
52
- timeout = timeout == :default ? @configuration.shutdown_timeout : timeout
52
+ timeout = @configuration.shutdown_timeout if timeout == :default
53
53
  GoodJob._shutdown_all([@notifier, @poller, @scheduler, @cron_manager].compact, timeout: timeout)
54
54
  @startable = false
55
55
  @running = false
@@ -3,11 +3,12 @@
3
3
  module GoodJob # :nodoc:
4
4
  class Notifier # :nodoc:
5
5
  # Extends the Notifier to register the process in the database.
6
- module ProcessRegistration
6
+ module ProcessHeartbeat
7
7
  extend ActiveSupport::Concern
8
8
 
9
9
  included do
10
10
  set_callback :listen, :after, :register_process
11
+ set_callback :tick, :before, :refresh_process
11
12
  set_callback :unlisten, :after, :deregister_process
12
13
  end
13
14
 
@@ -19,6 +20,14 @@ module GoodJob # :nodoc:
19
20
  end
20
21
  end
21
22
 
23
+ def refresh_process
24
+ GoodJob::Process.with_connection(connection) do
25
+ Process.logger.silence do
26
+ @process&.refresh_if_stale(cleanup: true)
27
+ end
28
+ end
29
+ end
30
+
22
31
  # Deregisters the current process.
23
32
  def deregister_process
24
33
  GoodJob::Process.with_connection(connection) do
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  require 'active_support/core_ext/module/attribute_accessors_per_thread'
3
3
  require 'concurrent/atomic/atomic_boolean'
4
- require "good_job/notifier/process_registration"
4
+ require "good_job/notifier/process_heartbeat"
5
5
 
6
6
  module GoodJob # :nodoc:
7
7
  #
@@ -13,9 +13,9 @@ module GoodJob # :nodoc:
13
13
  #
14
14
  class Notifier
15
15
  include ActiveSupport::Callbacks
16
- define_callbacks :listen, :unlisten
16
+ define_callbacks :listen, :tick, :unlisten
17
17
 
18
- include Notifier::ProcessRegistration
18
+ include ProcessHeartbeat
19
19
 
20
20
  # Default Postgres channel for LISTEN/NOTIFY
21
21
  CHANNEL = 'good_job'
@@ -189,18 +189,20 @@ module GoodJob # :nodoc:
189
189
  end
190
190
 
191
191
  while thr_executor.running?
192
- wait_for_notify do |channel, payload|
193
- next unless channel == CHANNEL
194
-
195
- ActiveSupport::Notifications.instrument("notifier_notified.good_job", { payload: payload })
196
- parsed_payload = JSON.parse(payload, symbolize_names: true)
197
- thr_recipients.each do |recipient|
198
- target, method_name = recipient.is_a?(Array) ? recipient : [recipient, :call]
199
- target.send(method_name, parsed_payload)
192
+ run_callbacks :tick do
193
+ wait_for_notify do |channel, payload|
194
+ next unless channel == CHANNEL
195
+
196
+ ActiveSupport::Notifications.instrument("notifier_notified.good_job", { payload: payload })
197
+ parsed_payload = JSON.parse(payload, symbolize_names: true)
198
+ thr_recipients.each do |recipient|
199
+ target, method_name = recipient.is_a?(Array) ? recipient : [recipient, :call]
200
+ target.send(method_name, parsed_payload)
201
+ end
200
202
  end
201
- end
202
203
 
203
- reset_connection_errors
204
+ reset_connection_errors
205
+ end
204
206
  end
205
207
  end
206
208
  ensure
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '3.15.12'
4
+ VERSION = '3.15.14'
5
5
 
6
6
  # GoodJob version as Gem::Version object
7
7
  GEM_VERSION = Gem::Version.new(VERSION)
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.15.12
4
+ version: 3.15.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ben Sheldon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-06-11 00:00:00.000000000 Z
11
+ date: 2023-07-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -393,6 +393,7 @@ files:
393
393
  - config/locales/ja.yml
394
394
  - config/locales/nl.yml
395
395
  - config/locales/ru.yml
396
+ - config/locales/tr.yml
396
397
  - config/locales/ua.yml
397
398
  - config/routes.rb
398
399
  - exe/good_job
@@ -427,7 +428,7 @@ files:
427
428
  - lib/good_job/log_subscriber.rb
428
429
  - lib/good_job/multi_scheduler.rb
429
430
  - lib/good_job/notifier.rb
430
- - lib/good_job/notifier/process_registration.rb
431
+ - lib/good_job/notifier/process_heartbeat.rb
431
432
  - lib/good_job/poller.rb
432
433
  - lib/good_job/probe_server.rb
433
434
  - lib/good_job/scheduler.rb