rescheduler 0.5.3 → 0.5.4

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/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