Class: Progressor
- Inherits:
-
Object
- Object
- Progressor
- Defined in:
- lib/progressor.rb
Overview
Used to measure the running time of parts of a long-running task and output an estimation based on the average of the last 10-100 measurements.
Example usage:
progressor = Progressor.new(total_count: Product.count)
Product.find_each do |product|
if product.not_something_we_want_to_process?
progressor.skip(1)
next
end
progressor.run do |progress|
puts "[#{progress}] Product #{product.id}"
product.calculate_interesting_stats
end
end
Example output:
...
[0038/1000, (004%), t/i: 0.5s, ETA: 8m:0.27s] Product 38
[0039/1000, (004%), t/i: 0.5s, ETA: 7m:58.47s] Product 39
[0040/1000, (004%), t/i: 0.5s, ETA: 7m:57.08s] Product 40
...
Constant Summary collapse
- VERSION =
'0.0.1'
Class Method Summary collapse
-
.puts(message, &block) ⇒ Object
Utility method to print a message with the time it took to run the contents of the block.
Instance Method Summary collapse
- #eta ⇒ Object
-
#initialize(total_count:) ⇒ Progressor
constructor
A new instance of Progressor.
- #per_iteration ⇒ Object
- #run ⇒ Object
- #skip(n) ⇒ Object
- #to_s ⇒ Object
Constructor Details
#initialize(total_count:) ⇒ Progressor
Returns a new instance of Progressor.
47 48 49 50 51 52 53 |
# File 'lib/progressor.rb', line 47 def initialize(total_count:) @total_count = total_count @total_count_digits = total_count.to_s.length @current = 0 @measurements = [] @averages = [] end |
Class Method Details
.puts(message, &block) ⇒ Object
Utility method to print a message with the time it took to run the contents of the block.
> Progressor.puts(“Working on a thing”) { thing_work }
Working on a thing… Working on a thing DONE: 2.1s
41 42 43 44 45 |
# File 'lib/progressor.rb', line 41 def self.puts(, &block) Kernel.puts "#{message}..." measurement = Benchmark.measure { block.call } Kernel.puts "#{message} DONE: #{format_time(measurement.real)}" end |
Instance Method Details
#eta ⇒ Object
88 89 90 91 92 93 |
# File 'lib/progressor.rb', line 88 def eta return nil if @measurements.count < 10 remaining_time = per_iteration * (@total_count - @current) remaining_time.round(2) end |
#per_iteration ⇒ Object
83 84 85 86 |
# File 'lib/progressor.rb', line 83 def per_iteration return nil if @measurements.count < 10 average(@averages) end |
#run ⇒ Object
55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/progressor.rb', line 55 def run @current += 1 measurement = Benchmark.measure { yield self } @measurements << measurement.real # only keep last 1000 @measurements.shift if @measurements.count > 1000 @averages << average(@measurements) @averages = @averages.compact # only keep last 100 @averages.shift if @averages.count > 100 end |
#skip(n) ⇒ Object
70 71 72 |
# File 'lib/progressor.rb', line 70 def skip(n) @total_count -= n end |
#to_s ⇒ Object
74 75 76 77 78 79 80 81 |
# File 'lib/progressor.rb', line 74 def to_s [ "#{@current.to_s.rjust(@total_count_digits, '0')}/#{@total_count}", "(#{((@current / @total_count.to_f) * 100).round.to_s.rjust(3, '0')}%)", "t/i: #{self.class.format_time(per_iteration)}", "ETA: #{self.class.format_time(eta)}", ].join(', ') end |