good_job 2.9.1 → 2.9.5

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: f99dea9840ebbfd8eda79dd1c06a94b7c9d8185835d6f9991e94d5a86fc5ffea
4
- data.tar.gz: 148b147b8f76c74f0362dcc8b26381631e1582eae4e7ab929021a291fa7d24fa
3
+ metadata.gz: c65c653e99d224dcc5803bd851fbc8891ecafd9634c68e4b0feaee08eafc1ed0
4
+ data.tar.gz: 6b6d8a61555bfacdf6ba82e69afa48a3d05c1c9d9239770cea86878067151727
5
5
  SHA512:
6
- metadata.gz: fe4926720862cb1e42581aa612b92c46ed9a00ea183b66a6c9ee4836165a7f77aa10b78ed32c80399bdc39189f76cd5f48e7b98e3b9b7da93b0de71c8b3cd0c7
7
- data.tar.gz: 1e47650d6bbdca91983bce0df607e4e4845cd26339d87798086a85f89be822987c2c41cfab08aba164f89195c55d10b3129e593b873b95dfb4075d452e3541c2
6
+ metadata.gz: 9135ae904e9031c97d9029af23d15b504b03383fbff4c43634416199a130d04ddafbd121ababe7f9675d997d1b5be8db37d098e060f4a51193035abe087052c8
7
+ data.tar.gz: 30235ec67f81832b6c9b7401a01c7e167d239fef9d38b5be4d83d56c98cb061bb8737432092bce7e18e7136f67c4df14dc917f83c227f3d0e83b578b9fe58468
data/CHANGELOG.md CHANGED
@@ -1,18 +1,86 @@
1
1
  # Changelog
2
2
 
3
- ## [v2.9.1](https://github.com/bensheldon/good_job/tree/v2.9.1) (2022-01-13)
3
+ ## [v2.9.5](https://github.com/bensheldon/good_job/tree/v2.9.5) (2022-02-07)
4
4
 
5
- [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.0...v2.9.1)
5
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.4...v2.9.5)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Transactions in "aborting" threads do not commit; causes GoodJob::Process record not destroyed on exit [\#489](https://github.com/bensheldon/good_job/issues/489)
10
+ - Deserialize ActiveJob arguments when manually retrying a job [\#513](https://github.com/bensheldon/good_job/pull/513) ([bensheldon](https://github.com/bensheldon))
6
11
 
7
12
  **Closed issues:**
8
13
 
9
- - Graceful fallback to polling when LISTEN/NOTIFY isn't available [\#482](https://github.com/bensheldon/good_job/issues/482)
10
- - Long running locks on latest good job [\#480](https://github.com/bensheldon/good_job/issues/480)
14
+ - Concurrency key proc is missing `arguments` when retrying a discarded job. [\#512](https://github.com/bensheldon/good_job/issues/512)
15
+ - Cron Schedule not visible in dashboard [\#496](https://github.com/bensheldon/good_job/issues/496)
16
+
17
+ **Merged pull requests:**
18
+
19
+ - Rename methods to `advisory_lock_key` and allow it to take a block instead of `with_advisory_lock` [\#511](https://github.com/bensheldon/good_job/pull/511) ([bensheldon](https://github.com/bensheldon))
20
+ - README: Limiting concurrency - fetch symbol instead of string [\#510](https://github.com/bensheldon/good_job/pull/510) ([BenSto](https://github.com/BenSto))
21
+ - Add arbitrary lock on class level too [\#499](https://github.com/bensheldon/good_job/pull/499) ([pandwoter](https://github.com/pandwoter))
22
+
23
+ ## [v2.9.4](https://github.com/bensheldon/good_job/tree/v2.9.4) (2022-01-31)
24
+
25
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.3...v2.9.4)
26
+
27
+ **Fixed bugs:**
28
+
29
+ - Fix navbar toggler [\#506](https://github.com/bensheldon/good_job/pull/506) ([JuanVqz](https://github.com/JuanVqz))
30
+ - Guard LogSubscriber against tagged logger without a formatter [\#504](https://github.com/bensheldon/good_job/pull/504) ([bensheldon](https://github.com/bensheldon))
31
+ - Markdown lint fixes + Added missing responsive meta tag [\#492](https://github.com/bensheldon/good_job/pull/492) ([zeevy](https://github.com/zeevy))
32
+
33
+ **Closed issues:**
34
+
35
+ - The navbar icon doesn't show the navbar menu when clicking it [\#503](https://github.com/bensheldon/good_job/issues/503)
36
+ - Not all loggers have a formatter [\#502](https://github.com/bensheldon/good_job/issues/502)
37
+ - Error logs from failed jobs used all storage space [\#495](https://github.com/bensheldon/good_job/issues/495)
38
+
39
+ **Merged pull requests:**
40
+
41
+ - Update Code of Conduct to Contributor Covenant 2.1 [\#501](https://github.com/bensheldon/good_job/pull/501) ([bensheldon](https://github.com/bensheldon))
42
+ - Test with Ruby 3.1 [\#498](https://github.com/bensheldon/good_job/pull/498) ([aried3r](https://github.com/aried3r))
43
+
44
+ ## [v2.9.3](https://github.com/bensheldon/good_job/tree/v2.9.3) (2022-01-23)
45
+
46
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.2...v2.9.3)
47
+
48
+ **Fixed bugs:**
49
+
50
+ - Use `*_url` route helpers for Dashboard assets to avoid being overridden by `config.asset_host` [\#493](https://github.com/bensheldon/good_job/pull/493) ([bensheldon](https://github.com/bensheldon))
51
+
52
+ **Closed issues:**
53
+
54
+ - Assets not loaded when Rails is configured with a different hostname for assets [\#491](https://github.com/bensheldon/good_job/issues/491)
55
+
56
+ ## [v2.9.2](https://github.com/bensheldon/good_job/tree/v2.9.2) (2022-01-19)
57
+
58
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.1...v2.9.2)
59
+
60
+ **Fixed bugs:**
61
+
62
+ - Error on GJ admin UI search form [\#487](https://github.com/bensheldon/good_job/issues/487)
63
+ - Use `websearch_to_tsquery` or \(`plainto_tsquery` for Postgres \< v11\) for Dashboard search filter [\#488](https://github.com/bensheldon/good_job/pull/488) ([bensheldon](https://github.com/bensheldon))
11
64
 
12
65
  **Merged pull requests:**
13
66
 
67
+ - Update README to illustrate using named arguments for the unique key. [\#486](https://github.com/bensheldon/good_job/pull/486) ([phallstrom](https://github.com/phallstrom))
68
+ - Add details about exactly where to require the engine. [\#485](https://github.com/bensheldon/good_job/pull/485) ([phallstrom](https://github.com/phallstrom))
69
+ - $ symbol gets copied when clicking on the copy button [\#484](https://github.com/bensheldon/good_job/pull/484) ([zeevy](https://github.com/zeevy))
70
+
71
+ ## [v2.9.1](https://github.com/bensheldon/good_job/tree/v2.9.1) (2022-01-13)
72
+
73
+ [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.9.0...v2.9.1)
74
+
75
+ **Fixed bugs:**
76
+
14
77
  - Start async adapters once `ActiveRecord` and `ActiveJob` have loaded, potentially before `Rails.application.initialized?` [\#483](https://github.com/bensheldon/good_job/pull/483) ([bensheldon](https://github.com/bensheldon))
15
78
 
79
+ **Closed issues:**
80
+
81
+ - Graceful fallback to polling when LISTEN/NOTIFY isn't available [\#482](https://github.com/bensheldon/good_job/issues/482)
82
+ - Long running locks on latest good job [\#480](https://github.com/bensheldon/good_job/issues/480)
83
+
16
84
  ## [v2.9.0](https://github.com/bensheldon/good_job/tree/v2.9.0) (2022-01-09)
17
85
 
18
86
  [Full Changelog](https://github.com/bensheldon/good_job/compare/v2.8.1...v2.9.0)
data/README.md CHANGED
@@ -73,19 +73,19 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
73
73
  1. Install the gem:
74
74
 
75
75
  ```bash
76
- $ bundle install
76
+ bundle install
77
77
  ```
78
78
 
79
79
  1. Run the GoodJob install generator. This will generate a database migration to create a table for GoodJob's job records:
80
80
 
81
81
  ```bash
82
- $ bin/rails g good_job:install
82
+ bin/rails g good_job:install
83
83
  ```
84
84
 
85
85
  Run the migration:
86
86
 
87
87
  ```bash
88
- $ bin/rails db:migrate
88
+ bin/rails db:migrate
89
89
  ```
90
90
 
91
91
  Optional: If using Rails' multiple databases with the `migrations_paths` configuration option, use the `--database` option:
@@ -119,7 +119,7 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
119
119
  - By default, GoodJob separates job enqueuing from job execution so that jobs can be scaled independently of the web server. Use the GoodJob command-line tool to execute jobs:
120
120
 
121
121
  ```bash
122
- $ bundle exec good_job start
122
+ bundle exec good_job start
123
123
  ```
124
124
 
125
125
  Ideally the command-line tool should be run on a separate machine or container from the web process. For example, on Heroku:
@@ -133,8 +133,8 @@ For more of the story of GoodJob, read the [introductory blog post](https://isla
133
133
 
134
134
  - GoodJob can also be configured to execute jobs within the web server process to save on resources. This is useful for low-workloads when economy is paramount.
135
135
 
136
- ```
137
- $ GOOD_JOB_EXECUTION_MODE=async rails server
136
+ ```bash
137
+ GOOD_JOB_EXECUTION_MODE=async rails server
138
138
  ```
139
139
 
140
140
  Additional configuration is likely necessary, see the reference below for configuration.
@@ -328,7 +328,7 @@ _🚧 GoodJob's dashboard is a work in progress. Please contribute ideas and cod
328
328
 
329
329
  GoodJob includes a Dashboard as a mountable `Rails::Engine`.
330
330
 
331
- 1. Explicitly require the Engine code at the top of your `config/application.rb` file, immediately after Rails is required. This is necessary because the mountable engine is an optional feature of GoodJob.
331
+ 1. Explicitly require the Engine code at the top of your `config/application.rb` file, immediately after Rails is required and before Bundler requires the Rails' groups. This is necessary because the mountable engine is an optional feature of GoodJob.
332
332
 
333
333
  ```ruby
334
334
  # config/application.rb
@@ -339,6 +339,8 @@ GoodJob includes a Dashboard as a mountable `Rails::Engine`.
339
339
  # ...
340
340
  ```
341
341
 
342
+ Note: If you find the dashboard fails to reload due to a routing error and uninitialized constant `GoodJob::ExecutionsController`, this is likely because you are not requiring the engine early enough.
343
+
342
344
  1. Mount the engine in your `config/routes.rb` file. The following will mount it at `http://example.com/good_job`.
343
345
 
344
346
  ```ruby
@@ -397,8 +399,9 @@ class MyJob < ApplicationJob
397
399
 
398
400
  # A unique key to be globally locked against.
399
401
  # Can be String or Lambda/Proc that is invoked in the context of the job.
400
- # Note: Arguments passed to #perform_later must be accessed through `arguments` method.
401
- key: -> { "Unique-#{arguments.first}" } # MyJob.perform_later("Alice") => "Unique-Alice"
402
+ # Note: Arguments passed to #perform_later can be accessed through ActiveJob's `arguments` method
403
+ # which is an array containing positional arguments and, optionally, a kwarg hash.
404
+ key: -> { "Unique-#{arguments.first}-#{arguments.last[:version]}" } # MyJob.perform_later("Alice", version: 'v2') => "Unique-Alice-v2"
402
405
  )
403
406
 
404
407
  def perform(first_name)
@@ -465,7 +468,7 @@ To perform upgrades to the GoodJob database tables:
465
468
  Optional: If using Rails' multiple databases with the `migrations_paths` configuration option, use the `--database` option:
466
469
 
467
470
  ```bash
468
- $ bin/rails g good_job:update --database animals
471
+ bin/rails g good_job:update --database animals
469
472
  ```
470
473
 
471
474
  1. Run the database migration locally
@@ -698,7 +701,7 @@ GoodJob can execute jobs "async" in the same process as the web server (e.g. `bi
698
701
  - Or, with environment variables:
699
702
 
700
703
  ```bash
701
- $ GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server
704
+ GOOD_JOB_EXECUTION_MODE=async GOOD_JOB_MAX_THREADS=4 GOOD_JOB_POLL_INTERVAL=30 bin/rails server
702
705
  ```
703
706
 
704
707
  Depending on your application configuration, you may need to take additional steps:
@@ -816,7 +819,7 @@ It is also necessary to delete these preserved jobs from the database after a ce
816
819
  - For example, using the `good_job` command-line utility:
817
820
 
818
821
  ```bash
819
- $ bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400
822
+ bundle exec good_job cleanup_preserved_jobs --before-seconds-ago=86400
820
823
  ```
821
824
 
822
825
  ### PgBouncer compatibility
@@ -2,23 +2,26 @@
2
2
  <html lang="en">
3
3
  <head>
4
4
  <title>Good Job Dashboard</title>
5
+ <meta charset="utf-8">
6
+ <meta content="width=device-width, initial-scale=1, shrink-to-fit=no" name="viewport">
5
7
  <%= csrf_meta_tags %>
6
8
  <%= csp_meta_tag %>
7
9
 
8
- <%= stylesheet_link_tag bootstrap_path(format: :css, v: GoodJob::VERSION) %>
9
- <%= stylesheet_link_tag style_path(format: :css, v: GoodJob::VERSION) %>
10
+ <%# Assets must use *_url route helpers to avoid being overriden by config.asset_host %>
11
+ <%= stylesheet_link_tag bootstrap_url(format: :css, v: GoodJob::VERSION), skip_pipeline: true %>
12
+ <%= stylesheet_link_tag style_url(format: :css, v: GoodJob::VERSION) %>
10
13
 
11
- <%= javascript_include_tag bootstrap_path(format: :js, v: GoodJob::VERSION), nonce: true %>
12
- <%= javascript_include_tag chartjs_path(format: :js, v: GoodJob::VERSION), nonce: true %>
13
- <%= javascript_include_tag scripts_path(format: :js, v: GoodJob::VERSION), nonce: true %>
14
+ <%= javascript_include_tag bootstrap_url(format: :js, v: GoodJob::VERSION), nonce: true %>
15
+ <%= javascript_include_tag chartjs_url(format: :js, v: GoodJob::VERSION), nonce: true %>
16
+ <%= javascript_include_tag scripts_url(format: :js, v: GoodJob::VERSION), nonce: true %>
14
17
 
15
- <%= javascript_include_tag rails_ujs_path(format: :js, v: GoodJob::VERSION), nonce: true %>
18
+ <%= javascript_include_tag rails_ujs_url(format: :js, v: GoodJob::VERSION), nonce: true %>
16
19
  </head>
17
20
  <body>
18
21
  <nav class="navbar navbar-expand-lg navbar-light bg-light">
19
22
  <div class="container-fluid">
20
23
  <%= link_to "GoodJob 👍", root_path, class: 'navbar-brand mb-0 h1' %>
21
- <button class="navbar-toggler" type="button" data-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
24
+ <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
22
25
  <span class="navbar-toggler-icon"></span>
23
26
  </button>
24
27
 
@@ -30,7 +30,7 @@ module GoodJob
30
30
  key = job.good_job_concurrency_key
31
31
  next(block.call) if key.blank?
32
32
 
33
- GoodJob::Execution.new.with_advisory_lock(key: key, function: "pg_advisory_lock") do
33
+ GoodJob::Execution.advisory_lock_key(key, function: "pg_advisory_lock") do
34
34
  enqueue_concurrency = if enqueue_limit
35
35
  GoodJob::Execution.where(concurrency_key: key).unfinished.advisory_unlocked.count
36
36
  else
@@ -61,7 +61,7 @@ module GoodJob
61
61
  key = job.good_job_concurrency_key
62
62
  next if key.blank?
63
63
 
64
- GoodJob::Execution.new.with_advisory_lock(key: key, function: "pg_advisory_lock") do
64
+ GoodJob::Execution.advisory_lock_key(key, function: "pg_advisory_lock") do
65
65
  allowed_active_job_ids = GoodJob::Execution.where(concurrency_key: key).advisory_locked.order(Arel.sql("COALESCE(performed_at, scheduled_at, created_at) ASC")).limit(perform_limit).pluck(:active_job_id)
66
66
  # The current job has already been locked and will appear in the previous query
67
67
  raise GoodJob::ActiveJobExtensions::Concurrency::ConcurrencyExceededError unless allowed_active_job_ids.include? job.job_id
@@ -267,7 +267,9 @@ module GoodJob
267
267
  end
268
268
 
269
269
  def active_job
270
- ActiveJob::Base.deserialize(active_job_data)
270
+ ActiveJob::Base.deserialize(active_job_data).tap do |aj|
271
+ aj.send(:deserialize_arguments_if_needed)
272
+ end
271
273
  end
272
274
 
273
275
  private
@@ -34,9 +34,18 @@ module GoodJob
34
34
  next if query.blank?
35
35
 
36
36
  tsvector = "(to_tsvector('english', serialized_params) || to_tsvector('english', id::text) || to_tsvector('english', COALESCE(error, '')::text))"
37
- where("#{tsvector} @@ to_tsquery(?)", query)
38
- .order(sanitize_sql_for_order([Arel.sql("ts_rank(#{tsvector}, to_tsquery(?))"), query]) => 'DESC')
37
+ to_tsquery_function = database_supports_websearch_to_tsquery? ? 'websearch_to_tsquery' : 'plainto_tsquery'
38
+ where("#{tsvector} @@ #{to_tsquery_function}(?)", query)
39
+ .order(sanitize_sql_for_order([Arel.sql("ts_rank(#{tsvector}, #{to_tsquery_function}(?))"), query]) => 'DESC')
39
40
  end)
40
41
  end
42
+
43
+ class_methods do
44
+ def database_supports_websearch_to_tsquery?
45
+ return @_database_supports_websearch_to_tsquery if defined?(@_database_supports_websearch_to_tsquery)
46
+
47
+ @_database_supports_websearch_to_tsquery = connection.postgresql_version >= 110000
48
+ end
49
+ end
41
50
  end
42
51
  end
@@ -148,6 +148,7 @@ module GoodJob
148
148
  raise ArgumentError, "Must provide a block" unless block_given?
149
149
 
150
150
  records = advisory_lock(column: column, function: function).to_a
151
+
151
152
  begin
152
153
  unscoped { yield(records) }
153
154
  ensure
@@ -161,6 +162,53 @@ module GoodJob
161
162
  end
162
163
  end
163
164
 
165
+ # Acquires an advisory lock on this record if it is not already locked by
166
+ # another database session. Be careful to ensure you release the lock when
167
+ # you are done with {#advisory_unlock_key} to release all remaining locks.
168
+ # @param key [String, Symbol] Key to Advisory Lock against
169
+ # @param function [String, Symbol] Postgres Advisory Lock function name to use
170
+ # @return [Boolean] whether the lock was acquired.
171
+ def advisory_lock_key(key, function: advisory_lockable_function)
172
+ query = if function.include? "_try_"
173
+ <<~SQL.squish
174
+ SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint) AS locked
175
+ SQL
176
+ else
177
+ <<~SQL.squish
178
+ SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint)::text AS locked
179
+ SQL
180
+ end
181
+
182
+ binds = [
183
+ ActiveRecord::Relation::QueryAttribute.new('key', key, ActiveRecord::Type::String.new),
184
+ ]
185
+ locked = connection.exec_query(pg_or_jdbc_query(query), 'GoodJob::Lockable Advisory Lock', binds).first['locked']
186
+ return locked unless block_given?
187
+ return nil unless locked
188
+
189
+ begin
190
+ yield
191
+ ensure
192
+ advisory_unlock_key(key, function: advisory_unlockable_function(function))
193
+ end
194
+ end
195
+
196
+ # Releases an advisory lock on this record if it is locked by this database
197
+ # session. Note that advisory locks stack, so you must call
198
+ # {#advisory_unlock} and {#advisory_lock} the same number of times.
199
+ # @param key [String, Symbol] Key to lock against
200
+ # @param function [String, Symbol] Postgres Advisory Lock function name to use
201
+ # @return [Boolean] whether the lock was released.
202
+ def advisory_unlock_key(key, function: advisory_unlockable_function)
203
+ query = <<~SQL.squish
204
+ SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint) AS unlocked
205
+ SQL
206
+ binds = [
207
+ ActiveRecord::Relation::QueryAttribute.new('key', key, ActiveRecord::Type::String.new),
208
+ ]
209
+ connection.exec_query(pg_or_jdbc_query(query), 'GoodJob::Lockable Advisory Unlock', binds).first['unlocked']
210
+ end
211
+
164
212
  def _advisory_lockable_column
165
213
  advisory_lockable_column || primary_key
166
214
  end
@@ -205,20 +253,7 @@ module GoodJob
205
253
  # @param function [String, Symbol] Postgres Advisory Lock function name to use
206
254
  # @return [Boolean] whether the lock was acquired.
207
255
  def advisory_lock(key: lockable_key, function: advisory_lockable_function)
208
- query = if function.include? "_try_"
209
- <<~SQL.squish
210
- SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint) AS locked
211
- SQL
212
- else
213
- <<~SQL.squish
214
- SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint)::text AS locked
215
- SQL
216
- end
217
-
218
- binds = [
219
- ActiveRecord::Relation::QueryAttribute.new('key', key, ActiveRecord::Type::String.new),
220
- ]
221
- self.class.connection.exec_query(pg_or_jdbc_query(query), 'GoodJob::Lockable Advisory Lock', binds).first['locked']
256
+ self.class.advisory_lock_key(key, function: function)
222
257
  end
223
258
 
224
259
  # Releases an advisory lock on this record if it is locked by this database
@@ -228,13 +263,7 @@ module GoodJob
228
263
  # @param function [String, Symbol] Postgres Advisory Lock function name to use
229
264
  # @return [Boolean] whether the lock was released.
230
265
  def advisory_unlock(key: lockable_key, function: self.class.advisory_unlockable_function(advisory_lockable_function))
231
- query = <<~SQL.squish
232
- SELECT #{function}(('x'||substr(md5($1::text), 1, 16))::bit(64)::bigint) AS unlocked
233
- SQL
234
- binds = [
235
- ActiveRecord::Relation::QueryAttribute.new('key', key, ActiveRecord::Type::String.new),
236
- ]
237
- self.class.connection.exec_query(pg_or_jdbc_query(query), 'GoodJob::Lockable Advisory Unlock', binds).first['unlocked']
266
+ self.class.advisory_unlock_key(key, function: function)
238
267
  end
239
268
 
240
269
  # Acquires an advisory lock on this record or raises
@@ -245,8 +274,7 @@ module GoodJob
245
274
  # @raise [RecordAlreadyAdvisoryLockedError]
246
275
  # @return [Boolean] +true+
247
276
  def advisory_lock!(key: lockable_key, function: advisory_lockable_function)
248
- result = advisory_lock(key: key, function: function)
249
- result || raise(RecordAlreadyAdvisoryLockedError)
277
+ self.class.advisory_lock_key(key, function: function) || raise(RecordAlreadyAdvisoryLockedError)
250
278
  end
251
279
 
252
280
  # Acquires an advisory lock on this record and safely releases it after the
@@ -266,9 +294,11 @@ module GoodJob
266
294
  raise ArgumentError, "Must provide a block" unless block_given?
267
295
 
268
296
  advisory_lock!(key: key, function: function)
269
- yield
270
- ensure
271
- advisory_unlock(key: key, function: self.class.advisory_unlockable_function(function)) unless $ERROR_INFO.is_a? RecordAlreadyAdvisoryLockedError
297
+ begin
298
+ yield
299
+ ensure
300
+ advisory_unlock(key: key, function: self.class.advisory_unlockable_function(function))
301
+ end
272
302
  end
273
303
 
274
304
  # Tests whether this record has an advisory lock on it.
@@ -206,7 +206,7 @@ module GoodJob
206
206
  good_job_tag = ["ActiveJob"].freeze
207
207
 
208
208
  self.class.loggers.inject(block) do |inner, each_logger|
209
- if each_logger.respond_to?(:tagged)
209
+ if each_logger.respond_to?(:tagged) && each_logger.formatter
210
210
  tags_for_logger = if each_logger.formatter.current_tags.include?("ActiveJob")
211
211
  good_job_tag + tags
212
212
  else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  module GoodJob
3
3
  # GoodJob gem version.
4
- VERSION = '2.9.1'
4
+ VERSION = '2.9.5'
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: 2.9.1
4
+ version: 2.9.5
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-01-13 00:00:00.000000000 Z
11
+ date: 2022-02-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activejob