good_job 1.12.2 → 1.13.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: 0af2c2293c2a0970a95ac200776850daa396a91d75aeda3f4612de23ee951a5c
4
- data.tar.gz: c938c0efca849771e68b39634e56fbdacf2987a83bdf8115e8050b9c49da40c3
3
+ metadata.gz: b9c8c8a0842bb8b25ee147d92186ca5596d4dc0bdc1a9a7638a094dc80c41806
4
+ data.tar.gz: 30b21a20dbe0b6d81854e29448b1218494359dfeaf8ebc4e0a51d4aaa87ca101
5
5
  SHA512:
6
- metadata.gz: 3b4da4eec468271fc88260fc0abcdb6faaaa9e43532e5587338fdca0a4f92f89d4e4f780678fe2c74a714adb0e7a1af263fb0578193382ee8181e11c44aea20d
7
- data.tar.gz: 91f4ae034471774f5ec1915750ccbf1d9d6ad9cc68df4f5ffa4c0bf6bca57928115e6871a59d30d6bab79b22faa7a4a293d55f55c1bf2cc659d55c0c60049040
6
+ metadata.gz: c2a0663d5af40fd294a9409c249677f73b683f5d50a3d2af58f120749429789de6f650ad58d61cc3704d0fa8a5ccc6681982ed106df37cf2d64856895e63892a
7
+ data.tar.gz: 0c8f717f2d763ecec47acc6dae85cadf153847d51cce0daf9c5b07f4aa953f4b57b612a79f0ae38335e9ed44192017567286448e761f1bfa688a5a6f04401820
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [v1.13.0](https://github.com/bensheldon/good_job/tree/v1.13.0) (2021-08-18)
4
+
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.12.2...v1.13.0)
6
+
7
+ **Implemented enhancements:**
8
+
9
+ - Track if a GoodJob::Job has been subsequently retried [\#331](https://github.com/bensheldon/good_job/pull/331) ([bensheldon](https://github.com/bensheldon))
10
+ - Wrap and truncate error message, which can be a huge text [\#294](https://github.com/bensheldon/good_job/pull/294) ([morgoth](https://github.com/morgoth))
11
+
12
+ **Closed issues:**
13
+
14
+ - Add hyphen to lock string. e.g. "table\_name-column" instead of "table\_namecolumn [\#334](https://github.com/bensheldon/good_job/issues/334)
15
+ - Optimize db indexes in advance of v2.0.0 [\#332](https://github.com/bensheldon/good_job/issues/332)
16
+ - wait\_until in development? [\#330](https://github.com/bensheldon/good_job/issues/330)
17
+ - Race conditions in ActiveJob concurrency extension [\#325](https://github.com/bensheldon/good_job/issues/325)
18
+ - Store in database if a job has been ActiveJob retried [\#321](https://github.com/bensheldon/good_job/issues/321)
19
+ - Revisit and embrace concurrency control, scheduled jobs, and other extensions of ActiveJob [\#255](https://github.com/bensheldon/good_job/issues/255)
20
+ - Why 1 million jobs per day? [\#222](https://github.com/bensheldon/good_job/issues/222)
21
+
3
22
  ## [v1.12.2](https://github.com/bensheldon/good_job/tree/v1.12.2) (2021-08-13)
4
23
 
5
24
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v1.12.1...v1.12.2)
data/README.md CHANGED
@@ -10,7 +10,7 @@ GoodJob is a multithreaded, Postgres-based, ActiveJob backend for Ruby on Rails.
10
10
  - **Designed for ActiveJob.** Complete support for [async, queues, delays, priorities, timeouts, and retries](https://edgeguides.rubyonrails.org/active_job_basics.html) with near-zero configuration.
11
11
  - **Built for Rails.** Fully adopts Ruby on Rails [threading and code execution guidelines](https://guides.rubyonrails.org/threading_and_code_execution.html) with [Concurrent::Ruby](https://github.com/ruby-concurrency/concurrent-ruby).
12
12
  - **Backed by Postgres.** Relies upon Postgres integrity, session-level Advisory Locks to provide run-once safety and stay within the limits of `schema.rb`, and LISTEN/NOTIFY to reduce queuing latency.
13
- - **For most workloads.** Targets full-stack teams, economy-minded solo developers, and applications that enqueue less than 1-million jobs/day.
13
+ - **For most workloads.** Targets full-stack teams, economy-minded solo developers, and applications that enqueue 1-million jobs/day and more.
14
14
 
15
15
  For more of the story of GoodJob, read the [introductory blog post](https://island94.org/2020/07/introducing-goodjob-1-0).
16
16
 
@@ -19,7 +19,7 @@
19
19
  <td><%= job.serialized_params['job_class'] %></td>
20
20
  <td><%= job.queue_name %></td>
21
21
  <td><%= job.scheduled_at || job.created_at %></td>
22
- <td><%= job.error %></td>
22
+ <td class="text-break"><%= truncate(job.error, length: 1_000) %></td>
23
23
  <td>
24
24
  <%= tag.button "Preview", type: "button", class: "btn btn-sm btn-outline-primary", role: "button",
25
25
  data: {bs_toggle: "collapse", bs_target: "##{dom_id(job, 'params')}"},
@@ -16,6 +16,7 @@ class CreateGoodJobs < ActiveRecord::Migration[5.2]
16
16
  t.uuid :active_job_id
17
17
  t.text :concurrency_key
18
18
  t.text :cron_key
19
+ t.uuid :retried_good_job_id
19
20
  end
20
21
 
21
22
  add_index :good_jobs, :scheduled_at, where: "(finished_at IS NULL)", name: "index_good_jobs_on_scheduled_at"
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+ class AddRetriedGoodJobIdToGoodJobs < ActiveRecord::Migration[5.2]
3
+ def change
4
+ reversible do |dir|
5
+ dir.up do
6
+ # Ensure this incremental update migration is idempotent
7
+ # with monolithic install migration.
8
+ return if connection.column_exists?(:good_jobs, :retried_good_job_id)
9
+ end
10
+ end
11
+
12
+ add_column :good_jobs, :retried_good_job_id, :uuid
13
+ end
14
+ end
@@ -5,12 +5,6 @@ module GoodJob
5
5
  # Thread-local attributes for passing values from Instrumentation.
6
6
  # (Cannot use ActiveSupport::CurrentAttributes because ActiveJob resets it)
7
7
  module CurrentExecution
8
- # @!attribute [rw] active_job_id
9
- # @!scope class
10
- # ActiveJob ID
11
- # @return [String, nil]
12
- thread_mattr_accessor :active_job_id
13
-
14
8
  # @!attribute [rw] cron_key
15
9
  # @!scope class
16
10
  # Cron Key
@@ -29,14 +23,26 @@ module GoodJob
29
23
  # @return [Exception, nil]
30
24
  thread_mattr_accessor :error_on_retry
31
25
 
26
+ # @!attribute [rw] good_job
27
+ # @!scope class
28
+ # Cron Key
29
+ # @return [GoodJob::Job, nil]
30
+ thread_mattr_accessor :good_job
31
+
32
32
  # Resets attributes
33
33
  # @return [void]
34
34
  def self.reset
35
- self.active_job_id = nil
35
+ self.cron_key = nil
36
+ self.good_job = nil
36
37
  self.error_on_discard = nil
37
38
  self.error_on_retry = nil
38
39
  end
39
40
 
41
+ # @return [String] UUID of the currently executing GoodJob::Job
42
+ def self.active_job_id
43
+ good_job&.active_job_id
44
+ end
45
+
40
46
  # @return [Integer] Current process ID
41
47
  def self.process_id
42
48
  Process.pid
data/lib/good_job/job.rb CHANGED
@@ -52,6 +52,20 @@ module GoodJob
52
52
  end
53
53
  end
54
54
 
55
+ def self._migration_pending_warning
56
+ ActiveSupport::Deprecation.warn(<<~DEPRECATION)
57
+ GoodJob has pending database migrations. To create the migration files, run:
58
+
59
+ rails generate good_job:update
60
+
61
+ To apply the migration files, run:
62
+
63
+ rails db:migrate
64
+
65
+ DEPRECATION
66
+ nil
67
+ end
68
+
55
69
  # Get Jobs with given class name
56
70
  # @!method with_job_class
57
71
  # @!scope class
@@ -110,6 +124,18 @@ module GoodJob
110
124
  # @return [ActiveRecord::Relation]
111
125
  scope :running, -> { where.not(performed_at: nil).where(finished_at: nil) }
112
126
 
127
+ # Get Jobs that do not have subsequent retries
128
+ # @!method running
129
+ # @!scope class
130
+ # @return [ActiveRecord::Relation]
131
+ scope :head, -> { where(retried_good_job_id: nil) }
132
+
133
+ # Get Jobs have errored that will not be retried further
134
+ # @!method running
135
+ # @!scope class
136
+ # @return [ActiveRecord::Relation]
137
+ scope :dead, -> { head.where.not(error: nil) }
138
+
113
139
  # Get Jobs on queues that match the given queue string.
114
140
  # @!method queue_string(string)
115
141
  # @!scope class
@@ -199,7 +225,6 @@ module GoodJob
199
225
  def self.enqueue(active_job, scheduled_at: nil, create_with_advisory_lock: false)
200
226
  ActiveSupport::Notifications.instrument("enqueue_job.good_job", { active_job: active_job, scheduled_at: scheduled_at, create_with_advisory_lock: create_with_advisory_lock }) do |instrument_payload|
201
227
  good_job_args = {
202
- cron_key: CurrentExecution.cron_key,
203
228
  queue_name: active_job.queue_name.presence || DEFAULT_QUEUE_NAME,
204
229
  priority: active_job.priority || DEFAULT_PRIORITY,
205
230
  serialized_params: active_job.serialize,
@@ -210,31 +235,23 @@ module GoodJob
210
235
  if column_names.include?('active_job_id')
211
236
  good_job_args[:active_job_id] = active_job.job_id
212
237
  else
213
- ActiveSupport::Deprecation.warn(<<~DEPRECATION)
214
- GoodJob has pending database migrations. To create the migration files, run:
215
-
216
- rails generate good_job:update
217
-
218
- To apply the migration files, run:
219
-
220
- rails db:migrate
221
-
222
- DEPRECATION
238
+ _migration_pending_warning
223
239
  end
224
240
 
225
241
  if column_names.include?('concurrency_key')
226
242
  good_job_args[:concurrency_key] = active_job.good_job_concurrency_key if active_job.respond_to?(:good_job_concurrency_key)
227
243
  else
228
- ActiveSupport::Deprecation.warn(<<~DEPRECATION)
229
- GoodJob has pending database migrations. To create the migration files, run:
230
-
231
- rails generate good_job:update
232
-
233
- To apply the migration files, run:
234
-
235
- rails db:migrate
244
+ _migration_pending_warning
245
+ end
236
246
 
237
- DEPRECATION
247
+ if column_names.include?('cron_key')
248
+ if CurrentExecution.cron_key
249
+ good_job_args[:cron_key] = CurrentExecution.cron_key
250
+ elsif CurrentExecution.active_job_id == active_job.job_id
251
+ good_job_args[:cron_key] = CurrentExecution.good_job.cron_key
252
+ end
253
+ else
254
+ _migration_pending_warning
238
255
  end
239
256
 
240
257
  good_job = GoodJob::Job.new(**good_job_args)
@@ -244,6 +261,12 @@ module GoodJob
244
261
  good_job.save!
245
262
  active_job.provider_job_id = good_job.id
246
263
 
264
+ if column_names.include?('retried_good_job_id')
265
+ CurrentExecution.good_job.retried_good_job_id = good_job.id if CurrentExecution.good_job && CurrentExecution.good_job.active_job_id == active_job.job_id
266
+ else
267
+ _migration_pending_warning
268
+ end
269
+
247
270
  good_job
248
271
  end
249
272
  end
@@ -283,24 +306,19 @@ module GoodJob
283
306
  end
284
307
 
285
308
  def active_job_id
286
- super || serialized_params['job_id']
309
+ if self.class.column_names.include?('active_job_id')
310
+ super
311
+ else
312
+ self.class._migration_pending_warning
313
+ serialized_params['job_id']
314
+ end
287
315
  end
288
316
 
289
317
  def cron_key
290
318
  if self.class.column_names.include?('cron_key')
291
319
  super
292
320
  else
293
- ActiveSupport::Deprecation.warn(<<~DEPRECATION)
294
- GoodJob has pending database migrations. To create the migration files, run:
295
-
296
- rails generate good_job:update
297
-
298
- To apply the migration files, run:
299
-
300
- rails db:migrate
301
-
302
- DEPRECATION
303
-
321
+ self.class._migration_pending_warning
304
322
  nil
305
323
  end
306
324
  end
@@ -314,8 +332,7 @@ module GoodJob
314
332
  )
315
333
 
316
334
  GoodJob::CurrentExecution.reset
317
- GoodJob::CurrentExecution.active_job_id = active_job_id
318
- GoodJob::CurrentExecution.cron_key = cron_key
335
+ GoodJob::CurrentExecution.good_job = self
319
336
  ActiveSupport::Notifications.instrument("perform_job.good_job", { good_job: self, process_id: GoodJob::CurrentExecution.process_id, thread_name: GoodJob::CurrentExecution.thread_name }) do
320
337
  value = ActiveJob::Base.execute(params)
321
338
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '1.12.2'
4
+ VERSION = '1.13.0'
5
5
  end
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: 1.12.2
4
+ version: 1.13.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: 2021-08-13 00:00:00.000000000 Z
11
+ date: 2021-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob
@@ -374,6 +374,7 @@ files:
374
374
  - lib/generators/good_job/templates/update/migrations/01_create_good_jobs.rb
375
375
  - lib/generators/good_job/templates/update/migrations/02_add_active_job_id_concurrency_key_cron_key_to_good_jobs.rb
376
376
  - lib/generators/good_job/templates/update/migrations/03_add_active_job_id_index_and_concurrency_key_index_to_good_jobs.rb
377
+ - lib/generators/good_job/templates/update/migrations/04_add_retried_good_job_id_to_good_jobs.rb
377
378
  - lib/generators/good_job/update_generator.rb
378
379
  - lib/good_job.rb
379
380
  - lib/good_job/active_job_extensions.rb