good_job 3.20.0 → 3.21.0

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: 62d33742278a734dd514fc3147abd1393ee62c3fd644c4c065b10c4fc6a24755
4
- data.tar.gz: 83d56214ec454cbc3d910d4cbefb0413877ca3b18577168c0d9b9b456385a7a3
3
+ metadata.gz: f1e8a8a3ec28224d48f23c9c2795cd15f9eb515ba9059ab2bea4316a03b42aa9
4
+ data.tar.gz: e469a0f1be765789433ef9d0096c6c1c3fe3e87c90a184c11996a204a36dabd1
5
5
  SHA512:
6
- metadata.gz: 90a3730d4989f26837b0ac9cd8f15ea3029f0c1c474159a4798a58d695153cb2067c336d382f971ba42a6faf371f677f7b295741c8ab1557add7c6b403a1fa94
7
- data.tar.gz: 684e5d8473b4f460707394fd670067b0aaf7a2749ed525be2893967c0953ed1c5afe4f35e8acfce4acaa7f7fa39ae00d16394b38d186a11f7eb8812839d65ff3
6
+ metadata.gz: 6546caba43d15714d87c2b6f3a072b493804685411f7fdd3c73b8aaa0aacffb2f77ae8fcbb8f3eb0d9aeed9fbfab2c4175b49adebd3d5356a8994138b92e3852
7
+ data.tar.gz: 30f85524258b9f1b2b774601ef0fd23965ed21eac87b0a3c0491a94c0fe85a3c70efb57b9979d11047d8ea5176cf0008317c860c27411db86ecdf8ef2fd0a69c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## [v3.21.0](https://github.com/bensheldon/good_job/tree/v3.21.0) (2023-11-06)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.20.0...v3.21.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Add "cron enabled" column to processes index page [\#1127](https://github.com/bensheldon/good_job/pull/1127) ([bforma](https://github.com/bforma))
10
+ - Add `limit:` kwarg to `GoodJob.perform_inline` [\#1126](https://github.com/bensheldon/good_job/pull/1126) ([bensheldon](https://github.com/bensheldon))
11
+
12
+ **Closed issues:**
13
+
14
+ - Cron scheduler and multiple processes [\#1128](https://github.com/bensheldon/good_job/issues/1128)
15
+ - `GoodJob.on_thread_error` not called in tests [\#1102](https://github.com/bensheldon/good_job/issues/1102)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - Use a Concurrent::Event for CLI signal-trapping loop [\#1141](https://github.com/bensheldon/good_job/pull/1141) ([bensheldon](https://github.com/bensheldon))
20
+ - Update README's optimize queue explanation [\#1138](https://github.com/bensheldon/good_job/pull/1138) ([maestromac](https://github.com/maestromac))
21
+ - Update development dependencies and light Rubocop'ing [\#1136](https://github.com/bensheldon/good_job/pull/1136) ([bensheldon](https://github.com/bensheldon))
22
+ - Move the Rails app harness from `spec/test_app` to `demo` [\#1135](https://github.com/bensheldon/good_job/pull/1135) ([bensheldon](https://github.com/bensheldon))
23
+ - In test, shutdown schedulers/capsules before doing assertions because of race conditions; store CI logs for Dev Env tests [\#1129](https://github.com/bensheldon/good_job/pull/1129) ([bensheldon](https://github.com/bensheldon))
24
+ - Use a constant to represent `None` for default/blank memoizable values [\#1125](https://github.com/bensheldon/good_job/pull/1125) ([bensheldon](https://github.com/bensheldon))
25
+
3
26
  ## [v3.20.0](https://github.com/bensheldon/good_job/tree/v3.20.0) (2023-10-23)
4
27
 
5
28
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v3.19.4...v3.20.0)
data/README.md CHANGED
@@ -939,7 +939,7 @@ By default, GoodJob creates a single thread execution pool that will execute job
939
939
 
940
940
  - `transactional_messages:2`: execute jobs enqueued on `transactional_messages`, with up to 2 threads.
941
941
  - `batch_processing:1` execute jobs enqueued on `batch_processing`, with a single thread.
942
- - `-transactional_messages,batch_processing`: execute jobs enqueued on _any_ queue _excluding_ `transactional_messages` or `batch_processing`, with up to 2 threads.
942
+ - `-transactional_messages,batch_processing:2`: execute jobs enqueued on _any_ queue _excluding_ `transactional_messages` or `batch_processing`, with up to 2 threads.
943
943
  - `*`: execute jobs on any queue, with up to 5 threads (as configured by `--max-threads=5`).
944
944
 
945
945
  When a pool is performing jobs from multiple queues, jobs will be performed from specified queues, ordered by priority and creation time. To perform jobs from queues in the queues' given order, use the `+` modifier. In this example, jobs in `batch_processing` will be performed only when there are no jobs in `transactional_messages`:
@@ -1370,7 +1370,7 @@ bin/setup
1370
1370
 
1371
1371
  #### Rails development harness
1372
1372
 
1373
- A Rails application exists within `spec/test_app` that is used for development, test, and GoodJob Demo environments.
1373
+ A Rails application exists within `demo` that is used for development, test, and GoodJob Demo environments.
1374
1374
 
1375
1375
  ```bash
1376
1376
  # Run a local development webserver
@@ -8,6 +8,7 @@
8
8
  <div class="row small text-muted text-uppercase align-items-center">
9
9
  <div class="col"><%= t ".process" %></div>
10
10
  <div class="col"><%= t ".schedulers" %></div>
11
+ <div class="col-2 d-flex gap-2"><%= t ".cron_enabled" %></div>
11
12
  <div class="col-2 d-flex gap-2">
12
13
  <span><%= t ".started" %></span>
13
14
  </div>
@@ -44,6 +45,7 @@
44
45
  <pre class="mb-0"><%= scheduler.is_a?(Hash) ? scheduler['name'] : scheduler %></pre>
45
46
  <% end %>
46
47
  </div>
48
+ <div class="col-2 small"><%= t(ActiveModel::Type::Boolean.new.cast(process.state["cron_enabled"]), scope: "good_job.shared.boolean") %></div>
47
49
  <div class="col-2 small"><%= relative_time(process.created_at) %></div>
48
50
  <div class="col-2 small"><%= relative_time(process.updated_at) %></div>
49
51
  <div class="col-auto">
@@ -198,6 +198,7 @@ de:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron aktiviert
201
202
  no_good_job_processes_found: Keine GoodJob-Prozesse gefunden.
202
203
  process: Verfahren
203
204
  schedulers: Planer
@@ -205,6 +206,9 @@ de:
205
206
  title: Prozesse
206
207
  updated: Aktualisiert
207
208
  shared:
209
+ boolean:
210
+ 'false': Nein
211
+ 'true': Ja
208
212
  error: Fehler
209
213
  filter:
210
214
  all: Alle
@@ -198,6 +198,7 @@ en:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron enabled
201
202
  no_good_job_processes_found: No GoodJob processes found.
202
203
  process: Process
203
204
  schedulers: Schedulers
@@ -205,6 +206,9 @@ en:
205
206
  title: Processes
206
207
  updated: Updated
207
208
  shared:
209
+ boolean:
210
+ 'false': 'No'
211
+ 'true': 'Yes'
208
212
  error: Error
209
213
  filter:
210
214
  all: All
@@ -196,6 +196,7 @@ es:
196
196
  unit: ''
197
197
  processes:
198
198
  index:
199
+ cron_enabled: Cron habilitado
199
200
  no_good_job_processes_found: No hay procesos de GoodJob.
200
201
  process: Proceso
201
202
  schedulers: Schedulers
@@ -203,6 +204,9 @@ es:
203
204
  title: Procesos
204
205
  updated: Actualizado
205
206
  shared:
207
+ boolean:
208
+ 'false': 'No'
209
+ 'true': Sí
206
210
  error: Error
207
211
  filter:
208
212
  all: Todas
@@ -198,6 +198,7 @@ fr:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron activé
201
202
  no_good_job_processes_found: Aucun processus GoodJob trouvé.
202
203
  process: Processus
203
204
  schedulers: Schedulers
@@ -205,6 +206,9 @@ fr:
205
206
  title: Processus
206
207
  updated: Mis à jour
207
208
  shared:
209
+ boolean:
210
+ 'false': Non
211
+ 'true': Oui
208
212
  error: Erreur
209
213
  filter:
210
214
  all: Tous
@@ -198,6 +198,7 @@ ja:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron が有効になっている
201
202
  no_good_job_processes_found: GoodJobのプロセスが見つかりませんでした。
202
203
  process: プロセス
203
204
  schedulers: スケジューラー
@@ -205,6 +206,9 @@ ja:
205
206
  title: プロセス
206
207
  updated: 更新された
207
208
  shared:
209
+ boolean:
210
+ 'false': いいえ
211
+ 'true': はい
208
212
  error: エラー
209
213
  filter:
210
214
  all: 全て
@@ -198,6 +198,7 @@ nl:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron ingeschakeld
201
202
  no_good_job_processes_found: Geen GoodJob-processen gevonden.
202
203
  process: Proces
203
204
  schedulers: Planners
@@ -205,6 +206,9 @@ nl:
205
206
  title: Processen
206
207
  updated: Bijgewerkt
207
208
  shared:
209
+ boolean:
210
+ 'false': Nee
211
+ 'true': Ja
208
212
  error: Fout
209
213
  filter:
210
214
  all: Alle
@@ -224,6 +224,7 @@ ru:
224
224
  unit: ''
225
225
  processes:
226
226
  index:
227
+ cron_enabled: Крон включен
227
228
  no_good_job_processes_found: Процессы GoodJob не найдены.
228
229
  process: Процесс
229
230
  schedulers: Планировщики
@@ -231,6 +232,9 @@ ru:
231
232
  title: Процессы
232
233
  updated: Обновлено
233
234
  shared:
235
+ boolean:
236
+ 'false': Нет
237
+ 'true': Да
234
238
  error: Ошибка
235
239
  filter:
236
240
  all: Все
@@ -198,6 +198,7 @@ tr:
198
198
  unit: ''
199
199
  processes:
200
200
  index:
201
+ cron_enabled: Cron etkin
201
202
  no_good_job_processes_found: GoodJob süreci bulunamadı.
202
203
  process: Süreç
203
204
  schedulers: Planlayıcılar
@@ -205,6 +206,9 @@ tr:
205
206
  title: Süreçler
206
207
  updated: Güncellenmiş
207
208
  shared:
209
+ boolean:
210
+ 'false': Hayır
211
+ 'true': Evet
208
212
  error: Hata
209
213
  filter:
210
214
  all: Tümü
@@ -224,6 +224,7 @@ uk:
224
224
  unit: ''
225
225
  processes:
226
226
  index:
227
+ cron_enabled: Cron увімкнено
227
228
  no_good_job_processes_found: Процеси GoodJob не знайдені.
228
229
  process: Процес
229
230
  schedulers: Планувальники
@@ -231,6 +232,9 @@ uk:
231
232
  title: Процеси
232
233
  updated: Оновлено
233
234
  shared:
235
+ boolean:
236
+ 'false': Ні
237
+ 'true': Так
234
238
  error: Помилка
235
239
  filter:
236
240
  all: Всі
@@ -168,13 +168,13 @@ module GoodJob
168
168
  end
169
169
 
170
170
  # Shut down the thread pool executors.
171
- # @param timeout [nil, Numeric, Symbol] Seconds to wait for active threads.
171
+ # @param timeout [nil, Numeric, NONE] Seconds to wait for active threads.
172
172
  # * +nil+ trigger a shutdown but not wait for it to complete.
173
173
  # * +-1+ wait until the shutdown is complete.
174
174
  # * +0+ immediately shutdown and stop any threads.
175
175
  # * A positive number will wait that many seconds before stopping any remaining active threads.
176
176
  # @return [void]
177
- def shutdown(timeout: :default)
177
+ def shutdown(timeout: NONE)
178
178
  @capsule&.shutdown(timeout: timeout)
179
179
  @_async_started = false
180
180
  end
@@ -44,23 +44,23 @@ module GoodJob
44
44
  end
45
45
 
46
46
  # Shut down the thread pool executors.
47
- # @param timeout [nil, Numeric, Symbol] Seconds to wait for active threads.
47
+ # @param timeout [nil, Numeric, NONE] Seconds to wait for active threads.
48
48
  # * +-1+ will wait for all active threads to complete.
49
49
  # * +0+ will interrupt active threads.
50
50
  # * +N+ will wait at most N seconds and then interrupt active threads.
51
51
  # * +nil+ will trigger a shutdown but not wait for it to complete.
52
52
  # @return [void]
53
- def shutdown(timeout: :default)
54
- timeout = @configuration.shutdown_timeout if timeout == :default
53
+ def shutdown(timeout: NONE)
54
+ timeout = @configuration.shutdown_timeout if timeout == NONE
55
55
  GoodJob._shutdown_all([@shared_executor, @notifier, @poller, @scheduler, @cron_manager].compact, timeout: timeout)
56
56
  @startable = false
57
57
  @running = false
58
58
  end
59
59
 
60
60
  # Shutdown and then start the capsule again.
61
- # @param timeout [Numeric, Symbol] Seconds to wait for active threads.
61
+ # @param timeout [Numeric, NONE] Seconds to wait for active threads.
62
62
  # @return [void]
63
- def restart(timeout: :default)
63
+ def restart(timeout: NONE)
64
64
  raise ArgumentError, "Capsule#restart cannot be called with a timeout of nil" if timeout.nil?
65
65
 
66
66
  shutdown(timeout: timeout)
data/lib/good_job/cli.rb CHANGED
@@ -17,6 +17,9 @@ module GoodJob
17
17
  # Requiring this loads the application's configuration and classes.
18
18
  RAILS_ENVIRONMENT_RB = File.expand_path("config/environment.rb")
19
19
 
20
+ # Number of seconds between checking shutdown conditions
21
+ SHUTDOWN_EVENT_TIMEOUT = 10
22
+
20
23
  class << self
21
24
  # Whether the CLI is running from the executable
22
25
  # @return [Boolean, nil]
@@ -106,14 +109,15 @@ module GoodJob
106
109
  probe_server.start
107
110
  end
108
111
 
109
- @stop_good_job_executable = false
112
+ require 'concurrent/atomic/event'
113
+ @stop_good_job_executable = Concurrent::Event.new
110
114
  %w[INT TERM].each do |signal|
111
- trap(signal) { @stop_good_job_executable = true }
115
+ trap(signal) { Thread.new { @stop_good_job_executable.set }.join }
112
116
  end
113
117
 
114
118
  Kernel.loop do
115
- sleep 0.1
116
- break if @stop_good_job_executable || capsule.shutdown?
119
+ @stop_good_job_executable.wait(SHUTDOWN_EVENT_TIMEOUT)
120
+ break if @stop_good_job_executable.set? || capsule.shutdown?
117
121
  end
118
122
 
119
123
  systemd.stop do
@@ -2,7 +2,7 @@
2
2
 
3
3
  module GoodJob
4
4
  # GoodJob gem version.
5
- VERSION = '3.20.0'
5
+ VERSION = '3.21.0'
6
6
 
7
7
  # GoodJob version as Gem::Version object
8
8
  GEM_VERSION = Gem::Version.new(VERSION)
data/lib/good_job.rb CHANGED
@@ -42,6 +42,10 @@ require "good_job/systemd_service"
42
42
  module GoodJob
43
43
  include GoodJob::Dependencies
44
44
 
45
+ # Default, null, blank value placeholder.
46
+ NONE = Module.new.freeze
47
+
48
+ # Default logger for GoodJob; overridden by Rails.logger in Railtie.
45
49
  DEFAULT_LOGGER = ActiveSupport::TaggedLogging.new(ActiveSupport::Logger.new($stdout))
46
50
 
47
51
  # @!attribute [rw] active_record_parent_class
@@ -233,13 +237,19 @@ module GoodJob
233
237
  # This is primarily intended for usage in a test environment.
234
238
  # Unhandled job errors will be raised.
235
239
  # @param queue_string [String] Queues to execute jobs from
240
+ # @param limit [Integer, nil] Maximum number of iterations for the loop
236
241
  # @return [void]
237
- def self.perform_inline(queue_string = "*")
242
+ def self.perform_inline(queue_string = "*", limit: nil)
238
243
  job_performer = JobPerformer.new(queue_string)
244
+ iteration = 0
239
245
  loop do
246
+ break if limit && iteration >= limit
247
+
240
248
  result = Rails.application.reloader.wrap { job_performer.next }
241
249
  break unless result
242
250
  raise result.unhandled_error if result.unhandled_error
251
+
252
+ iteration += 1
243
253
  end
244
254
  end
245
255
 
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.20.0
4
+ version: 3.21.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: 2023-10-23 00:00:00.000000000 Z
11
+ date: 2023-11-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob