boy_band 0.1.7 → 0.1.12
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 +4 -4
- data/lib/boy_band.rb +133 -23
- 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: b6d040e078153295146fa37e5781a107ad5aea4dd16727dc3d63bcd4e25821d2
|
|
4
|
+
data.tar.gz: ea5ae60dc466b1a660666d4db41d6c0a0e1b690f8ee2b9d2c1830936f9faae8a
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db4df288e482fb66d80d370d522a64bb60c7d32d2aeb14eaaa2ddb03742cd78b00ed3455acb151f00168a0dcc6339c4ae44e4758293ba1085a9009cc42b3ea1c
|
|
7
|
+
data.tar.gz: 57ea5a67822e98c108c30ff200c971b68136f4a459069353d1899705ecc47eca1193829b701a8f56a36c8b49962c2f018edd179137110f3be5d3f673af045932
|
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,15 @@ 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
|
-
|
|
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('+')}")
|
|
57
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")
|
|
60
75
|
end
|
|
61
76
|
job_count = Resque.redis.get("jobs_from_#{chain[0]}")
|
|
62
77
|
if job_count && job_count.to_i > 50
|
|
@@ -79,21 +94,21 @@ module BoyBand
|
|
|
79
94
|
end
|
|
80
95
|
|
|
81
96
|
def note_job(hash)
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
# Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
|
88
|
-
|
|
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
|
|
89
104
|
end
|
|
90
105
|
|
|
91
106
|
def clear_job(hash)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
# Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
|
|
96
|
-
|
|
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
|
|
97
112
|
end
|
|
98
113
|
|
|
99
114
|
def schedule(klass, method_name, *args)
|
|
@@ -111,8 +126,13 @@ module BoyBand
|
|
|
111
126
|
def in_worker_process?
|
|
112
127
|
BoyBand.job_instigator.match(/^job/)
|
|
113
128
|
end
|
|
129
|
+
|
|
130
|
+
def current_speed
|
|
131
|
+
@speed
|
|
132
|
+
end
|
|
114
133
|
|
|
115
134
|
def perform_at(speed, *args)
|
|
135
|
+
@speed = speed
|
|
116
136
|
args_copy = [] + args
|
|
117
137
|
if args_copy[-1].is_a?(String) && args_copy[-1].match(/^chain::/)
|
|
118
138
|
set_job_chain(args_copy.pop.split(/::/, 2)[1])
|
|
@@ -124,6 +144,7 @@ module BoyBand
|
|
|
124
144
|
klass = Object.const_get(klass_string)
|
|
125
145
|
method_name = args_copy.shift
|
|
126
146
|
job_hash = Digest::MD5.hexdigest(args_copy.to_json)
|
|
147
|
+
Resque.redis.del("scheduled/#{klass_string}/#{method_name}/#{job_hash}")
|
|
127
148
|
hash = args_copy[0] if args_copy[0].is_a?(Hash)
|
|
128
149
|
hash ||= {'method' => method_name}
|
|
129
150
|
action = "#{klass_string} . #{hash['method']} (#{hash['id']})"
|
|
@@ -144,6 +165,7 @@ module BoyBand
|
|
|
144
165
|
set_job_chain("none")
|
|
145
166
|
BoyBand.set_job_instigator(pre_whodunnit)
|
|
146
167
|
clear_job(job_hash)
|
|
168
|
+
@speed = nil
|
|
147
169
|
rescue Resque::TermException
|
|
148
170
|
Resque.enqueue(self, *args)
|
|
149
171
|
end
|
|
@@ -178,6 +200,68 @@ module BoyBand
|
|
|
178
200
|
end
|
|
179
201
|
res
|
|
180
202
|
end
|
|
203
|
+
|
|
204
|
+
def root_actions(queue='default')
|
|
205
|
+
idx = Resque.size(queue)
|
|
206
|
+
job_ids = {}
|
|
207
|
+
idx.times do |i|
|
|
208
|
+
item = Resque.peek(queue, i)
|
|
209
|
+
chain = nil
|
|
210
|
+
if item && item['args'] && item['args'][-1].match(/^chain::/)
|
|
211
|
+
chain = item['args'].pop
|
|
212
|
+
end
|
|
213
|
+
if chain
|
|
214
|
+
parts = chain.split(/##/)
|
|
215
|
+
job_ids[parts[0]] ||= [parts[1], 0, []]
|
|
216
|
+
job_ids[parts[0]][1] += 1
|
|
217
|
+
job_ids[parts[0]][2] << parts.length - 2
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
job_ids.each{|k, v| job_ids.delete(k) if v[1] <= 5}.length
|
|
221
|
+
job_ids
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
def action_types(queue='default')
|
|
225
|
+
idx = Resque.size(queue)
|
|
226
|
+
list = []
|
|
227
|
+
idx.times do |i|
|
|
228
|
+
item = Resque.peek(queue, i)
|
|
229
|
+
chain = nil
|
|
230
|
+
if item && item['args'] && item['args'][-1].match(/^chain::/)
|
|
231
|
+
chain = item['args'].pop
|
|
232
|
+
end
|
|
233
|
+
if chain
|
|
234
|
+
match = chain.scan(/##/)
|
|
235
|
+
if match && match.length == 1
|
|
236
|
+
item['root'] = true
|
|
237
|
+
list << item
|
|
238
|
+
elsif match && match.length > 1
|
|
239
|
+
list << item
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
count = {'root' => {}, 'non_root' => {}}
|
|
244
|
+
list.each do |item|
|
|
245
|
+
key = "#{item['args'][0]}::#{item['args'][2].is_a?(Hash) ? item['args'][2]['method'] : item['args'][1]}"
|
|
246
|
+
count[item['root'] ? 'root' : 'non_root'][key] ||= 0
|
|
247
|
+
count[item['root'] ? 'root' : 'non_root'][key] += 1
|
|
248
|
+
end.length
|
|
249
|
+
count
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def find_actions(method)
|
|
253
|
+
queue = 'default'
|
|
254
|
+
idx = Resque.size(queue)
|
|
255
|
+
list = []
|
|
256
|
+
idx.times do |i|
|
|
257
|
+
item = Resque.peek(queue, i)
|
|
258
|
+
if item['args'] && item['args'][2].is_a?(Hash) && item['args'][2]['method'] == method
|
|
259
|
+
list << item
|
|
260
|
+
puts item.to_json
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
list
|
|
264
|
+
end
|
|
181
265
|
|
|
182
266
|
def scheduled_for?(queue, klass, method_name, *args)
|
|
183
267
|
args_copy = [] + args
|
|
@@ -188,6 +272,10 @@ module BoyBand
|
|
|
188
272
|
set_domain_id(args_copy.pop.split(/::/, 2)[1])
|
|
189
273
|
end
|
|
190
274
|
|
|
275
|
+
idx = queue_size(queue)
|
|
276
|
+
job_hash = args_copy.to_json
|
|
277
|
+
return true if Resque.redis.get("scheduled/#{klass.to_s}/#{method_name}/#{job_hash}") == "t"
|
|
278
|
+
return false if idx > 500 # big queues mustn't be searched this way
|
|
191
279
|
idx = Resque.size(queue)
|
|
192
280
|
queue_class = (queue == :slow ? 'SlowWorker' : 'Worker')
|
|
193
281
|
if false
|
|
@@ -312,6 +400,10 @@ module BoyBand
|
|
|
312
400
|
|
|
313
401
|
module AsyncInstanceMethods
|
|
314
402
|
def schedule(method, *args)
|
|
403
|
+
schedule_for('default', method, *args)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def schedule_for(queue, method, *args)
|
|
315
407
|
return nil unless method
|
|
316
408
|
id = self.id
|
|
317
409
|
settings = {
|
|
@@ -320,19 +412,23 @@ module BoyBand
|
|
|
320
412
|
'scheduled' => self.class.scheduled_stamp,
|
|
321
413
|
'arguments' => args
|
|
322
414
|
}
|
|
323
|
-
Worker.
|
|
415
|
+
Worker.schedule_for(queue, self.class, :perform_action, settings)
|
|
324
416
|
end
|
|
325
|
-
|
|
417
|
+
|
|
326
418
|
def schedule_once(method, *args)
|
|
419
|
+
schedule_once_for('default', method, *args)
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
def schedule_once_for(queue, method, *args)
|
|
327
423
|
return nil unless method && id
|
|
328
|
-
already_scheduled = Worker.
|
|
424
|
+
already_scheduled = Worker.scheduled_for?(queue, self.class, :perform_action, {
|
|
329
425
|
'id' => id,
|
|
330
426
|
'method' => method,
|
|
331
427
|
'scheduled' => self.class.scheduled_stamp,
|
|
332
428
|
'arguments' => args
|
|
333
429
|
})
|
|
334
430
|
if !already_scheduled
|
|
335
|
-
|
|
431
|
+
schedule_for(queue, method, *args)
|
|
336
432
|
else
|
|
337
433
|
false
|
|
338
434
|
end
|
|
@@ -357,23 +453,37 @@ module BoyBand
|
|
|
357
453
|
'scheduled' => self.scheduled_stamp,
|
|
358
454
|
'arguments' => args
|
|
359
455
|
}
|
|
360
|
-
|
|
456
|
+
schedule_for('default', method, *args)
|
|
361
457
|
end
|
|
362
458
|
|
|
459
|
+
def schedule_for(queue, method, *args)
|
|
460
|
+
return nil unless method
|
|
461
|
+
settings = {
|
|
462
|
+
'method' => method,
|
|
463
|
+
'scheduled' => self.scheduled_stamp,
|
|
464
|
+
'arguments' => args
|
|
465
|
+
}
|
|
466
|
+
Worker.schedule_for(queue, self, :perform_action, settings)
|
|
467
|
+
end
|
|
468
|
+
|
|
363
469
|
def schedule_once(method, *args)
|
|
470
|
+
schedule_once_for('default', method, *args)
|
|
471
|
+
end
|
|
472
|
+
|
|
473
|
+
def schedule_once_for(queue, method, *args)
|
|
364
474
|
return nil unless method
|
|
365
|
-
already_scheduled = Worker.
|
|
475
|
+
already_scheduled = Worker.scheduled_for?(queue, self, :perform_action, {
|
|
366
476
|
'method' => method,
|
|
367
477
|
'scheduled' => self.scheduled_stamp,
|
|
368
478
|
'arguments' => args
|
|
369
479
|
})
|
|
370
480
|
if !already_scheduled
|
|
371
|
-
|
|
481
|
+
schedule_for(queue, method, *args)
|
|
372
482
|
else
|
|
373
483
|
false
|
|
374
484
|
end
|
|
375
485
|
end
|
|
376
|
-
|
|
486
|
+
|
|
377
487
|
def perform_action(settings)
|
|
378
488
|
obj = self
|
|
379
489
|
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.12
|
|
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
|