switchman-inst-jobs 4.0.10 → 4.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8663d7c19e1900c68ab1595b7306cc2105233b1aa02bb687beee88cdbfa9ada5
|
4
|
+
data.tar.gz: 63f99e858a89ff31c8cda4a1dd35e072e58cda21ebf9d1cdb6a7434ad37f5968
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0322296a92637bb28cc00cfe41446fc39eb189fb4c5e433fb1adf115f1ab80204d91228c96a5902d5f2ece3906805e478ecf166dee37ef9d17b7ce9d4c28c1bd'
|
7
|
+
data.tar.gz: 769694ebfd1343c2449b18b14b8883aaab0cf3819e01446878328461542657d31df576501db5539f572cf5bae8ca5c460354e960e4c27f3b3996a6c3439894c4
|
@@ -9,6 +9,16 @@ module SwitchmanInstJobs
|
|
9
9
|
@before_move_callbacks << proc
|
10
10
|
end
|
11
11
|
|
12
|
+
def add_validation_callback(proc)
|
13
|
+
@validation_callbacks ||= []
|
14
|
+
@validation_callbacks << proc
|
15
|
+
end
|
16
|
+
|
17
|
+
def clear_callbacks!
|
18
|
+
@before_move_callbacks = []
|
19
|
+
@validation_callbacks = []
|
20
|
+
end
|
21
|
+
|
12
22
|
def transaction_on(shards, &block)
|
13
23
|
return yield if shards.empty?
|
14
24
|
|
@@ -31,6 +41,10 @@ module SwitchmanInstJobs
|
|
31
41
|
source_shards << shard.delayed_jobs_shard.id
|
32
42
|
target_shard = target_shard.try(:id) || target_shard
|
33
43
|
target_shards[target_shard] += [shard.id]
|
44
|
+
|
45
|
+
@validation_callbacks&.each do |proc|
|
46
|
+
proc.call(shard: shard, target_shard: ::Switchman::Shard.find(target_shard))
|
47
|
+
end
|
34
48
|
end
|
35
49
|
|
36
50
|
# Do the updates in batches and then just clear redis instead of clearing them one at a time
|
@@ -81,6 +95,17 @@ module SwitchmanInstJobs
|
|
81
95
|
sleep(65) unless @skip_cache_wait
|
82
96
|
end
|
83
97
|
|
98
|
+
def acquire_advisory_lock(type, name)
|
99
|
+
@quoted_function_name ||= ::Delayed::Job.connection.quote_table_name('half_md5_as_bigint')
|
100
|
+
|
101
|
+
value = type == :singleton ? "singleton:#{name}" : name
|
102
|
+
::Delayed::Job.connection.execute(
|
103
|
+
::Delayed::Job.sanitize_sql_for_conditions(
|
104
|
+
["SELECT pg_advisory_xact_lock(#{@quoted_function_name}(?))", value]
|
105
|
+
)
|
106
|
+
)
|
107
|
+
end
|
108
|
+
|
84
109
|
# This method expects that all relevant shards already have block_stranded: true
|
85
110
|
# but otherwise jobs can be running normally
|
86
111
|
def run
|
@@ -167,15 +192,12 @@ module SwitchmanInstJobs
|
|
167
192
|
locked_by: ::Delayed::Backend::Base::ON_HOLD_BLOCKER
|
168
193
|
}
|
169
194
|
|
170
|
-
quoted_function_name = ::Delayed::Job.connection.quote_table_name('half_md5_as_bigint')
|
171
195
|
strand_advisory_lock_fn = lambda do |value|
|
172
|
-
|
196
|
+
acquire_advisory_lock(:strand, value)
|
173
197
|
end
|
174
198
|
|
175
199
|
singleton_advisory_lock_fn = lambda do |value|
|
176
|
-
|
177
|
-
"SELECT pg_advisory_xact_lock(#{quoted_function_name}('singleton:#{value}'))"
|
178
|
-
)
|
200
|
+
acquire_advisory_lock(:singleton, value)
|
179
201
|
end
|
180
202
|
|
181
203
|
handler.call(strand_scope, :strand, {}, strand_advisory_lock_fn)
|
@@ -203,12 +225,12 @@ module SwitchmanInstJobs
|
|
203
225
|
end
|
204
226
|
|
205
227
|
def unblock_strands(target_shard, batch_size: 10_000)
|
206
|
-
|
228
|
+
blocked_shard_ids = blocked_shards.pluck(:id)
|
207
229
|
query = lambda { |column, scope|
|
208
230
|
::Delayed::Job.
|
209
231
|
where(id: ::Delayed::Job.select("DISTINCT ON (#{column}) id").
|
210
232
|
where(scope).
|
211
|
-
where.not(shard_id:
|
233
|
+
where.not(shard_id: blocked_shard_ids).
|
212
234
|
where(
|
213
235
|
::Delayed::Job.select(1).from("#{::Delayed::Job.quoted_table_name} dj2").
|
214
236
|
where("dj2.next_in_strand = true OR dj2.source = 'JobsMigrator::StrandBlocker'").
|
@@ -250,6 +272,76 @@ module SwitchmanInstJobs
|
|
250
272
|
end
|
251
273
|
end
|
252
274
|
|
275
|
+
def blocked_shards
|
276
|
+
::Switchman::Shard.where(block_stranded: true).or(::Switchman::Shard.where(jobs_held: true))
|
277
|
+
end
|
278
|
+
|
279
|
+
def blocked_by_migrator?(job_scope)
|
280
|
+
job_scope.exists?(source: 'JobsMigrator::StrandBlocker') ||
|
281
|
+
blocked_shards.exists?(id: job_scope.distinct.pluck(:shard_id))
|
282
|
+
end
|
283
|
+
|
284
|
+
def blocked_strands
|
285
|
+
::Delayed::Job.
|
286
|
+
where.not(strand: nil).
|
287
|
+
group(:strand).
|
288
|
+
having('NOT BOOL_OR(next_in_strand)')
|
289
|
+
end
|
290
|
+
|
291
|
+
def unblock_strand!(strand, new_parallelism: nil)
|
292
|
+
job_scope = ::Delayed::Job.where(strand: strand)
|
293
|
+
raise JobsBlockedError if blocked_by_migrator?(job_scope)
|
294
|
+
|
295
|
+
::Delayed::Job.transaction do
|
296
|
+
acquire_advisory_lock(:strand, strand)
|
297
|
+
|
298
|
+
new_parallelism ||= job_scope.pick('MAX(max_concurrent)')
|
299
|
+
if new_parallelism
|
300
|
+
needed_jobs = new_parallelism - job_scope.where(next_in_strand: true).count
|
301
|
+
if needed_jobs.positive?
|
302
|
+
job_scope.where(next_in_strand: false, locked_by: nil,
|
303
|
+
singleton: nil).order(:strand_order_override, :id).
|
304
|
+
limit(needed_jobs).update_all(next_in_strand: true)
|
305
|
+
else
|
306
|
+
0
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
def blocked_singletons
|
313
|
+
::Delayed::Job.
|
314
|
+
where(strand: nil).
|
315
|
+
where.not(singleton: nil).
|
316
|
+
group(:singleton).
|
317
|
+
having('NOT BOOL_OR(next_in_strand)')
|
318
|
+
end
|
319
|
+
|
320
|
+
def unblock_singleton!(singleton)
|
321
|
+
job_scope = ::Delayed::Job.where(strand: nil, singleton: singleton)
|
322
|
+
raise JobsBlockedError if blocked_by_migrator?(job_scope)
|
323
|
+
|
324
|
+
::Delayed::Job.transaction do
|
325
|
+
acquire_advisory_lock(:singleton, singleton)
|
326
|
+
|
327
|
+
id, next_in_strand = job_scope.
|
328
|
+
group(:singleton).
|
329
|
+
pick('MIN(id), BOOL_OR(next_in_strand)')
|
330
|
+
|
331
|
+
if next_in_strand
|
332
|
+
0
|
333
|
+
elsif id
|
334
|
+
::Delayed::Job.where(id: id).update_all(next_in_strand: true)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
def blocked_job_count
|
340
|
+
::Delayed::Job.from(blocked_strands.select('count(id) AS ssize')).sum('ssize').to_i +
|
341
|
+
::Delayed::Job.from(blocked_singletons.select('count(id) AS ssize')).sum('ssize').to_i +
|
342
|
+
::Delayed::Job.where(strand: nil, singleton: nil, next_in_strand: false).count
|
343
|
+
end
|
344
|
+
|
253
345
|
private
|
254
346
|
|
255
347
|
def create_blocker_job(**kwargs)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: switchman-inst-jobs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bryan Petty
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-10-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: inst-jobs
|