boy_band 0.1.6 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/boy_band.rb +132 -24
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6931c59174a8d6eda05b764b143c11c38532c46ae0d68f41b35700539db6e45a
|
4
|
+
data.tar.gz: 7df882de888ee4ac4680d37006f437d5b26e9055f193f596486f6259bb75997e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c19f3dd8e840f87b903d97450adbbfe0ce92b236cbbdec0905b7e6f18c283dcf2dccc2372f731cfbcc53bde6e530e79061b6da072b1cf49f61fe1ab461daeb4
|
7
|
+
data.tar.gz: 41cbb91e46bc9dcb8169c95c5b0b458626692679fa21668a09281d2f4a40568c7595917f8ac35268612c674470ea09bda8c557c85ba931a475bfd068dd22167a
|
data/lib/boy_band.rb
CHANGED
@@ -39,12 +39,22 @@ module BoyBand
|
|
39
39
|
def set_job_chain(val)
|
40
40
|
@@job_chain = val
|
41
41
|
end
|
42
|
+
|
43
|
+
def queue_size(queue)
|
44
|
+
size = Resque.redis.get("sizeof/#{queue}").to_i
|
45
|
+
if !size || size == 0
|
46
|
+
size = Resque.size(queue)
|
47
|
+
Resque.redis.setex("sizeof/#{queue}", 30.seconds.to_i, size)
|
48
|
+
end
|
49
|
+
size
|
50
|
+
end
|
42
51
|
|
43
52
|
def schedule_for(queue, klass, method_name, *args)
|
53
|
+
queue = queue.to_sym
|
44
54
|
@queue = queue.to_s
|
45
55
|
job_hash = Digest::MD5.hexdigest(args.to_json)
|
46
56
|
note_job(job_hash)
|
47
|
-
size =
|
57
|
+
size = queue_size(queue)
|
48
58
|
args.push("domain::#{self.domain_id}")
|
49
59
|
chain = self.job_chain.split(/##/)
|
50
60
|
job_id = "j#{Time.now.iso8601}_#{rand(9999)}"
|
@@ -53,10 +63,19 @@ module BoyBand
|
|
53
63
|
Resque.redis.incr("jobs_from_#{chain[0]}")
|
54
64
|
Resque.redis.expire("jobs_from_#{chain[0]}", 24.hours.to_i)
|
55
65
|
end
|
56
|
-
|
57
|
-
|
66
|
+
Resque.redis.setex("scheduled/#{klass.to_s}/#{job_hash}", 6.hours, "t")
|
67
|
+
chain_args = args[0..-2]
|
68
|
+
if chain_args.length == 1 && chain_args[0].is_a?(Hash)
|
69
|
+
chain_args = [chain_args[0]['method'],chain_args[0]['id'],chain_args[0]['arguments'].to_s[0, 20]]
|
70
|
+
end
|
71
|
+
chain.push("#{klass.to_s},#{method_name.to_s},#{chain_args.join('+')}")
|
72
|
+
Rails.logger.warn("jobchain set, #{chain[0]} #{chain.join('##')}") if chain.length > 2
|
58
73
|
if chain.length > 5
|
59
|
-
Rails.logger.error("jobchain too
|
74
|
+
Rails.logger.error("jobchain too deep: #{chain[0]}, #{chain.length} entries")
|
75
|
+
end
|
76
|
+
job_count = Resque.redis.get("jobs_from_#{chain[0]}")
|
77
|
+
if job_count && job_count.to_i > 50
|
78
|
+
Rails.logger.error("jobchain too many sub-jobs: #{chain[0]}, #{job_count} so far")
|
60
79
|
end
|
61
80
|
args.push("chain::#{chain.join('##')}")
|
62
81
|
if queue == :slow
|
@@ -75,21 +94,21 @@ module BoyBand
|
|
75
94
|
end
|
76
95
|
|
77
96
|
def note_job(hash)
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
# Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
84
|
-
|
97
|
+
# if Resque.redis
|
98
|
+
# timestamps = JSON.parse(Resque.redis.hget('hashed_jobs', hash) || "[]")
|
99
|
+
# cutoff = 6.hours.ago.to_i
|
100
|
+
# timestamps = timestamps.select{|ts| ts > cutoff }
|
101
|
+
# timestamps.push(Time.now.to_i)
|
102
|
+
# # Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
103
|
+
# end
|
85
104
|
end
|
86
105
|
|
87
106
|
def clear_job(hash)
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
# Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
92
|
-
|
107
|
+
# if Resque.redis
|
108
|
+
# timestamps = JSON.parse(Resque.redis.hget('hashed_jobs', hash) || "[]")
|
109
|
+
# timestamps.shift
|
110
|
+
# # Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
111
|
+
# end
|
93
112
|
end
|
94
113
|
|
95
114
|
def schedule(klass, method_name, *args)
|
@@ -120,6 +139,7 @@ module BoyBand
|
|
120
139
|
klass = Object.const_get(klass_string)
|
121
140
|
method_name = args_copy.shift
|
122
141
|
job_hash = Digest::MD5.hexdigest(args_copy.to_json)
|
142
|
+
Resque.redis.del("scheduled/#{klass_string}/#{method_name}/#{job_hash}")
|
123
143
|
hash = args_copy[0] if args_copy[0].is_a?(Hash)
|
124
144
|
hash ||= {'method' => method_name}
|
125
145
|
action = "#{klass_string} . #{hash['method']} (#{hash['id']})"
|
@@ -174,6 +194,68 @@ module BoyBand
|
|
174
194
|
end
|
175
195
|
res
|
176
196
|
end
|
197
|
+
|
198
|
+
def root_actions(queue='default')
|
199
|
+
idx = Resque.size(queue)
|
200
|
+
job_ids = {}
|
201
|
+
idx.times do |i|
|
202
|
+
item = Resque.peek(queue, i)
|
203
|
+
chain = nil
|
204
|
+
if item && item['args'] && item['args'][-1].match(/^chain::/)
|
205
|
+
chain = item['args'].pop
|
206
|
+
end
|
207
|
+
if chain
|
208
|
+
parts = chain.split(/##/)
|
209
|
+
job_ids[parts[0]] ||= [parts[1], 0, []]
|
210
|
+
job_ids[parts[0]][1] += 1
|
211
|
+
job_ids[parts[0]][2] << parts.length - 2
|
212
|
+
end
|
213
|
+
end
|
214
|
+
job_ids.each{|k, v| job_ids.delete(k) if v[1] <= 5}.length
|
215
|
+
job_ids
|
216
|
+
end
|
217
|
+
|
218
|
+
def action_types(queue='default')
|
219
|
+
idx = Resque.size(queue)
|
220
|
+
list = []
|
221
|
+
idx.times do |i|
|
222
|
+
item = Resque.peek(queue, i)
|
223
|
+
chain = nil
|
224
|
+
if item && item['args'] && item['args'][-1].match(/^chain::/)
|
225
|
+
chain = item['args'].pop
|
226
|
+
end
|
227
|
+
if chain
|
228
|
+
match = chain.scan(/##/)
|
229
|
+
if match && match.length == 1
|
230
|
+
item['root'] = true
|
231
|
+
list << item
|
232
|
+
elsif match && match.length > 1
|
233
|
+
list << item
|
234
|
+
end
|
235
|
+
end
|
236
|
+
end
|
237
|
+
count = {'root' => {}, 'non_root' => {}}
|
238
|
+
list.each do |item|
|
239
|
+
key = "#{item['args'][0]}::#{item['args'][2].is_a?(Hash) ? item['args'][2]['method'] : item['args'][1]}"
|
240
|
+
count[item['root'] ? 'root' : 'non_root'][key] ||= 0
|
241
|
+
count[item['root'] ? 'root' : 'non_root'][key] += 1
|
242
|
+
end.length
|
243
|
+
count
|
244
|
+
end
|
245
|
+
|
246
|
+
def find_actions(method)
|
247
|
+
queue = 'default'
|
248
|
+
idx = Resque.size(queue)
|
249
|
+
list = []
|
250
|
+
idx.times do |i|
|
251
|
+
item = Resque.peek(queue, i)
|
252
|
+
if item['args'] && item['args'][2].is_a?(Hash) && item['args'][2]['method'] == method
|
253
|
+
list << item
|
254
|
+
puts item.to_json
|
255
|
+
end
|
256
|
+
end
|
257
|
+
list
|
258
|
+
end
|
177
259
|
|
178
260
|
def scheduled_for?(queue, klass, method_name, *args)
|
179
261
|
args_copy = [] + args
|
@@ -184,6 +266,10 @@ module BoyBand
|
|
184
266
|
set_domain_id(args_copy.pop.split(/::/, 2)[1])
|
185
267
|
end
|
186
268
|
|
269
|
+
idx = queue_size(queue)
|
270
|
+
job_hash = args_copy.to_json
|
271
|
+
return true if Resque.redis.get("scheduled/#{klass.to_s}/#{method_name}/#{job_hash}") == "t"
|
272
|
+
return false if idx > 500 # big queues mustn't be searched this way
|
187
273
|
idx = Resque.size(queue)
|
188
274
|
queue_class = (queue == :slow ? 'SlowWorker' : 'Worker')
|
189
275
|
if false
|
@@ -308,6 +394,10 @@ module BoyBand
|
|
308
394
|
|
309
395
|
module AsyncInstanceMethods
|
310
396
|
def schedule(method, *args)
|
397
|
+
schedule_for('default', method, *args)
|
398
|
+
end
|
399
|
+
|
400
|
+
def schedule_for(queue, method, *args)
|
311
401
|
return nil unless method
|
312
402
|
id = self.id
|
313
403
|
settings = {
|
@@ -316,19 +406,23 @@ module BoyBand
|
|
316
406
|
'scheduled' => self.class.scheduled_stamp,
|
317
407
|
'arguments' => args
|
318
408
|
}
|
319
|
-
Worker.
|
409
|
+
Worker.schedule_for(queue, self.class, :perform_action, settings)
|
320
410
|
end
|
321
|
-
|
411
|
+
|
322
412
|
def schedule_once(method, *args)
|
413
|
+
schedule_once_for('default', method, *args)
|
414
|
+
end
|
415
|
+
|
416
|
+
def schedule_once_for(queue, method, *args)
|
323
417
|
return nil unless method && id
|
324
|
-
already_scheduled = Worker.
|
418
|
+
already_scheduled = Worker.scheduled_for?(queue, self.class, :perform_action, {
|
325
419
|
'id' => id,
|
326
420
|
'method' => method,
|
327
421
|
'scheduled' => self.class.scheduled_stamp,
|
328
422
|
'arguments' => args
|
329
423
|
})
|
330
424
|
if !already_scheduled
|
331
|
-
|
425
|
+
schedule_for(queue, method, *args)
|
332
426
|
else
|
333
427
|
false
|
334
428
|
end
|
@@ -353,23 +447,37 @@ module BoyBand
|
|
353
447
|
'scheduled' => self.scheduled_stamp,
|
354
448
|
'arguments' => args
|
355
449
|
}
|
356
|
-
|
450
|
+
schedule_for('default', method, *args)
|
357
451
|
end
|
358
452
|
|
453
|
+
def schedule_for(queue, method, *args)
|
454
|
+
return nil unless method
|
455
|
+
settings = {
|
456
|
+
'method' => method,
|
457
|
+
'scheduled' => self.scheduled_stamp,
|
458
|
+
'arguments' => args
|
459
|
+
}
|
460
|
+
Worker.schedule_for(queue, self, :perform_action, settings)
|
461
|
+
end
|
462
|
+
|
359
463
|
def schedule_once(method, *args)
|
464
|
+
schedule_once_for('default', method, *args)
|
465
|
+
end
|
466
|
+
|
467
|
+
def schedule_once_for(queue, method, *args)
|
360
468
|
return nil unless method
|
361
|
-
already_scheduled = Worker.
|
469
|
+
already_scheduled = Worker.scheduled_for?(queue, self, :perform_action, {
|
362
470
|
'method' => method,
|
363
471
|
'scheduled' => self.scheduled_stamp,
|
364
472
|
'arguments' => args
|
365
473
|
})
|
366
474
|
if !already_scheduled
|
367
|
-
|
475
|
+
schedule_for(queue, method, *args)
|
368
476
|
else
|
369
477
|
false
|
370
478
|
end
|
371
479
|
end
|
372
|
-
|
480
|
+
|
373
481
|
def perform_action(settings)
|
374
482
|
obj = self
|
375
483
|
if settings['id']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: boy_band
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brian Whitmer
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-05-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|