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.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/boy_band.rb +133 -23
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8ffb5fe1ca9cf6df69908f6d6e950041be2f31d7336ad327e9381b9065933a3f
4
- data.tar.gz: 32406d34eaea92673d35fc7384104044d63d91f3e66e63e0971f317c8ef26312
3
+ metadata.gz: b6d040e078153295146fa37e5781a107ad5aea4dd16727dc3d63bcd4e25821d2
4
+ data.tar.gz: ea5ae60dc466b1a660666d4db41d6c0a0e1b690f8ee2b9d2c1830936f9faae8a
5
5
  SHA512:
6
- metadata.gz: 588c0aee54c064f87a9213faa3d1dd13a9d649a49b74a882a6afe095b4eef4f953ef521911c30cf72ed9c3f7455653b5455c5bcff15d4cd280d5e45c97e38d93
7
- data.tar.gz: 225a3091fca7f2535d54fec0477b8c538ddb5ff8a290b36a80f9756ef80ed98591d2b2567679f0779221e819908850ec769d4268a3bf284082fcaebd3ded8db6
6
+ metadata.gz: db4df288e482fb66d80d370d522a64bb60c7d32d2aeb14eaaa2ddb03742cd78b00ed3455acb151f00168a0dcc6339c4ae44e4758293ba1085a9009cc42b3ea1c
7
+ data.tar.gz: 57ea5a67822e98c108c30ff200c971b68136f4a459069353d1899705ecc47eca1193829b701a8f56a36c8b49962c2f018edd179137110f3be5d3f673af045932
@@ -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 = Resque.size(queue)
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
- chain.push("#{klass.to_s},#{method_name.to_s},#{args.join('+')}")
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 long: #{chain[0]}, #{chain.length} entries")
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
- if Resque.redis
83
- timestamps = JSON.parse(Resque.redis.hget('hashed_jobs', hash) || "[]")
84
- cutoff = 6.hours.ago.to_i
85
- timestamps = timestamps.select{|ts| ts > cutoff }
86
- timestamps.push(Time.now.to_i)
87
- # Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
88
- end
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
- if Resque.redis
93
- timestamps = JSON.parse(Resque.redis.hget('hashed_jobs', hash) || "[]")
94
- timestamps.shift
95
- # Resque.redis.hset('hashed_jobs', hash, timestamps.to_json)
96
- end
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.schedule(self.class, :perform_action, settings)
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.scheduled?(self.class, :perform_action, {
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
- schedule(method, *args)
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
- Worker.schedule(self, :perform_action, settings)
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.scheduled?(self, :perform_action, {
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
- schedule(method, *args)
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.7
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-02-13 00:00:00.000000000 Z
11
+ date: 2020-05-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails