inst-jobs 3.1.16 → 3.1.17

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: 4f72da158c53a425c974608dd30ca4f16f0c70071f3f159e16488b40677f2efe
4
- data.tar.gz: a039610f1a50c70abaf4f2b36f81a19e748429cd3c675c7c789703d0ba1f8d02
3
+ metadata.gz: 8b4b6a00b5e6b9ec0916e799819a8ae75aac19faa368e869772b336f860a8109
4
+ data.tar.gz: 8f6a562afbf654e5937a5dc4d2540304ead783bab594722ca5c3b5782f6fdeb6
5
5
  SHA512:
6
- metadata.gz: 6d5d65c583bd1e818918ffc927be4779129d556670d910dd7781a7c2c5be0d178e3315e1a8a1bfb1b0784d3b5b09be7b59187e402915c28a1e33fa726bad7c38
7
- data.tar.gz: 2cfbe4d0840eae6ee31941dd8b0b8a681c07ab2b6dcc3c832198198eb02a146c6068f8f83081f31f03e0a93a763c9fdd5f62767e5ab1383e1214cbc84489d1e1
6
+ metadata.gz: 4bbd25cfe653768aa2a755eab2c3ea45530debba4d86e12b8d5a1cfd169ddf3d59fc0fef9773a0e81b2abaeaf886e0dd7be2a208c22fc0e0323fec77205e64e7
7
+ data.tar.gz: 9a61ada6fb4f816c0dadaf159f0852d4a31d933dff50ad7dfb5e8439e0dfc09ce9c3c1baf2dc24ab79f41fa79b6ea0b4f703d4903248d436b576924c629511a6
@@ -47,11 +47,13 @@ module Delayed
47
47
 
48
48
  def attempt_advisory_lock(lock_name)
49
49
  fn_name = connection.quote_table_name("half_md5_as_bigint")
50
+ lock_name = connection.quote_string(lock_name)
50
51
  connection.select_value("SELECT pg_try_advisory_xact_lock(#{fn_name}('#{lock_name}'));")
51
52
  end
52
53
 
53
54
  def advisory_lock(lock_name)
54
55
  fn_name = connection.quote_table_name("half_md5_as_bigint")
56
+ lock_name = connection.quote_string(lock_name)
55
57
  connection.execute("SELECT pg_advisory_xact_lock(#{fn_name}('#{lock_name}'));")
56
58
  end
57
59
  end
@@ -409,7 +411,36 @@ module Delayed
409
411
  RETURNING #{quoted_table_name}.*
410
412
  SQL
411
413
 
412
- jobs = find_by_sql(query)
414
+ begin
415
+ jobs = find_by_sql(query)
416
+ rescue ::ActiveRecord::RecordNotUnique => e
417
+ # if we got a unique violation on a singleton, it's because next_in_strand
418
+ # somehow got set to true on the non-running job when there is a running
419
+ # job. AFAICT this is not possible from inst-jobs itself, but has happened
420
+ # in production - either due to manual manipulation of jobs, or possibly
421
+ # a process in something like switchman-inst-jobs
422
+ raise unless e.message.include?('"index_delayed_jobs_on_singleton_running"')
423
+
424
+ # just repair the "strand"
425
+ singleton = e.message.match(/Key \(singleton\)=\((.+)\) already exists.$/)[1]
426
+ raise unless singleton
427
+
428
+ transaction do
429
+ # very conservatively lock the locked job, so that it won't unlock from underneath us and
430
+ # leave an orphaned strand
431
+ advisory_lock("singleton:#{singleton}")
432
+ locked_jobs = where(singleton: singleton).where.not(locked_by: nil).lock.pluck(:id)
433
+ # if it's already gone, then we're good and should be able to just retry
434
+ if locked_jobs.length == 1
435
+ updated = where(singleton: singleton, next_in_strand: true)
436
+ .where(locked_by: nil)
437
+ .update_all(next_in_strand: false)
438
+ raise if updated.zero?
439
+ end
440
+ end
441
+
442
+ retry
443
+ end
413
444
  # because this is an atomic query, we don't have to return more jobs than we needed
414
445
  # to try and lock them, nor is there a possibility we need to try again because
415
446
  # all of the jobs we tried to lock had already been locked by someone else
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Delayed
4
- VERSION = "3.1.16"
4
+ VERSION = "3.1.17"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inst-jobs
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.16
4
+ version: 3.1.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cody Cutrer
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2024-04-01 00:00:00.000000000 Z
13
+ date: 2024-04-23 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activerecord
@@ -130,20 +130,6 @@ dependencies:
130
130
  - - ">="
131
131
  - !ruby/object:Gem::Version
132
132
  version: '0'
133
- - !ruby/object:Gem::Dependency
134
- name: byebug
135
- requirement: !ruby/object:Gem::Requirement
136
- requirements:
137
- - - ">="
138
- - !ruby/object:Gem::Version
139
- version: '0'
140
- type: :development
141
- prerelease: false
142
- version_requirements: !ruby/object:Gem::Requirement
143
- requirements:
144
- - - ">="
145
- - !ruby/object:Gem::Version
146
- version: '0'
147
133
  - !ruby/object:Gem::Dependency
148
134
  name: database_cleaner
149
135
  requirement: !ruby/object:Gem::Requirement
@@ -173,35 +159,35 @@ dependencies:
173
159
  - !ruby/object:Gem::Version
174
160
  version: '2.0'
175
161
  - !ruby/object:Gem::Dependency
176
- name: diplomat
162
+ name: debug
177
163
  requirement: !ruby/object:Gem::Requirement
178
164
  requirements:
179
- - - "~>"
165
+ - - ">="
180
166
  - !ruby/object:Gem::Version
181
- version: 2.6.3
167
+ version: '0'
182
168
  type: :development
183
169
  prerelease: false
184
170
  version_requirements: !ruby/object:Gem::Requirement
185
171
  requirements:
186
- - - "~>"
172
+ - - ">="
187
173
  - !ruby/object:Gem::Version
188
- version: 2.6.3
174
+ version: '0'
189
175
  - !ruby/object:Gem::Dependency
190
- name: pg
176
+ name: diplomat
191
177
  requirement: !ruby/object:Gem::Requirement
192
178
  requirements:
193
- - - ">="
179
+ - - "~>"
194
180
  - !ruby/object:Gem::Version
195
- version: '0'
181
+ version: 2.6.3
196
182
  type: :development
197
183
  prerelease: false
198
184
  version_requirements: !ruby/object:Gem::Requirement
199
185
  requirements:
200
- - - ">="
186
+ - - "~>"
201
187
  - !ruby/object:Gem::Version
202
- version: '0'
188
+ version: 2.6.3
203
189
  - !ruby/object:Gem::Dependency
204
- name: pry
190
+ name: pg
205
191
  requirement: !ruby/object:Gem::Requirement
206
192
  requirements:
207
193
  - - ">="