rescheduler 0.5.3 → 0.5.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rescheduler.rb +50 -6
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 85c352b4ca6259305ae8fa32ba0fc16c0c00aef0
4
- data.tar.gz: 7d54913d094dced68ae4210a791471e022495aad
3
+ metadata.gz: acc7eb77ebb2e60efc00c38a654b6eb3ac1fe6e3
4
+ data.tar.gz: cf12bd7f36e0e8135a2b1d88cd1de3f58deee044
5
5
  SHA512:
6
- metadata.gz: 6625da10818cf1aefdc48e3561c17c93d059939225bfdb784b0267771fc6b23db4d0ca89bff2b19fa112fa3bf2a5ad309624323dcf14dd09adb13cd75cc4ff3a
7
- data.tar.gz: a6838adb3e3e6f1618df27dbce9f6a9d361539ecebd173e1a458e0dcf2008e6a3ebc42728835e9d63e0b8791a09804de4f2929579bdb5af57bbd957232d755c2
6
+ metadata.gz: 99ea938055d68a8dd63ec75c459c2195b9ba6c3a2751a23dc5c3a523e482eb6632c0edc85daec05b557ef1314c893b2a2c83857c8f7aea0d30ee6789b0f6fa2d
7
+ data.tar.gz: ccb0f16410fe88f4aac4f091fb0f52a49c9e80371790dfc01d830dbf1eaa69869e0839d5bb58a486b0bcaff3ad729fb1be1eaa8418a245c8d0081afede248cf7
@@ -98,6 +98,34 @@ module Rescheduler
98
98
  return {:jobs=>stats, :workers=>Worker.stats}
99
99
  end
100
100
 
101
+ def eta(sample_time = 30)
102
+ print "Measuring ... "
103
+ jobs1 = stats[:jobs]
104
+ start = Time.zone.now
105
+ sleep sample_time
106
+ stop = Time.zone.now
107
+ jobs2 = stats[:jobs]
108
+ print "done!\n"
109
+
110
+ secs = stop - start
111
+ jobs = {}
112
+ jobs1.select {|k, v| (v[:immediate] || 0) > 1}.keys.each do |job|
113
+ j1_i = jobs1[job][:immediate]
114
+ j2_i = (jobs2[job] || {})[:immediate] || 0
115
+ diff = j1_i - j2_i
116
+ if diff == 0
117
+ jobs[job] = "No progress"
118
+ elsif diff < 0
119
+ jobs[job] = "Negative progress. Queue size increased."
120
+ else
121
+ secs_per_job = secs/diff.to_f
122
+ remaining = jobs2[job][:immediate] * secs_per_job
123
+ jobs[job] = {per_job: '%.2f' % secs_per_job, remaining: '%.2f' % remaining}
124
+ end
125
+ end
126
+ jobs
127
+ end
128
+
101
129
  #----------------------------------------------
102
130
  # Queue management
103
131
  #----------------------------------------------
@@ -276,6 +304,9 @@ module Rescheduler
276
304
  raise Exception, 'Can not start worker without defining job handlers.'
277
305
  end
278
306
 
307
+ start_opts = {}
308
+ start_opts = tubes.pop if tubes.last.is_a?(Hash)
309
+
279
310
  tubes.each do |t|
280
311
  next if @@runners.include?(t)
281
312
  raise Exception, "Handler for queue #{t} is undefined."
@@ -288,12 +319,8 @@ module Rescheduler
288
319
  # Generate a random clientkey for maintenance token ring maintenance.
289
320
  client_key = [[rand(0xFFFFFFFF)].pack('L')].pack('m0')[0...6]
290
321
 
291
- keys = tubes.map {|t| rk_queue(t)}
292
- keys << rk_maintenace
293
-
294
- # Queue to control a named worker
295
322
  worker_queue = Worker.rk_queue if Worker.named?
296
- keys.unshift(worker_queue) if worker_queue # worker control queue is the first we respond to
323
+ queues = construct_pri_queues(tubes.map {|t| rk_queue(t)})
297
324
 
298
325
  dopush = nil
299
326
 
@@ -318,7 +345,7 @@ module Rescheduler
318
345
  # This may not be desirable...
319
346
  # (too bad BRPOPLPUSH does not support multiple queues...)
320
347
  # TODO: Maybe LUA script is the way out of this.
321
- result = redis.brpop(keys, :timeout=>timeout)
348
+ result = redis.brpop(queues, :timeout=>timeout)
322
349
 
323
350
  # Handle task
324
351
  if result # Got a task
@@ -332,6 +359,8 @@ module Rescheduler
332
359
  Worker.handle_command(qnid)
333
360
  else
334
361
  run_job(qnid)
362
+ # Regenerate prioritized queue list based on current handled tasks, if we do round_robin
363
+ queues = construct_pri_queues(tubes.map {|t| rk_queue(t)}, tube) if start_opts[:round_robin]
335
364
  end
336
365
  else
337
366
  # Do nothing when got timeout, the run_maintenance will take care of deferred jobs
@@ -341,6 +370,21 @@ module Rescheduler
341
370
 
342
371
  def end_job_loop; @@end_job_loop = true; end
343
372
 
373
+ # Perform a "fair" round robin rotation of queues by rotating the "current" queue to the end of the list
374
+ private def construct_pri_queues(queues, current = nil)
375
+ idx = queues.index(current) if current
376
+ # Rotate if needed
377
+ queues = queues[(idx+1)..-1] + queues[0..idx] if idx && idx < queues.size - 1
378
+
379
+ # Prepend Queue to control a named worker
380
+ worker_queue = Worker.rk_queue if Worker.named?
381
+ queues.unshift(worker_queue) if worker_queue # worker control queue is the first we respond to
382
+
383
+ # Append rk_maintenance
384
+ queues << rk_maintenace
385
+ return queues
386
+ end
387
+
344
388
 
345
389
  # Logging facility
346
390
  def log_debug(msg)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rescheduler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.5.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dongyi Liao
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-07-25 00:00:00.000000000 Z
11
+ date: 2016-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: redis