ConsoleSourceConsoleProgress

class Progress

A simple progress indicator

Definitions

def self.now

  • deprecated

Signature

deprecated

Use Console::Clock.now instead.

Implementation

def self.now
	Clock.now
end

def initialize(subject, total = 0, minimum_output_duration: 0.1, **options)

Create a new progress indicator.

Signature

parameter subject Object

The subject of the progress indicator.

parameter total Integer

The total number of steps.

parameter minimum_output_duration Numeric

The minimum duration between outputs.

parameter options Hash

Additional options to customize the output.

Implementation

def initialize(subject, total = 0, minimum_output_duration: 0.1, **options)
	@subject = subject
	@options = options
	
	@start_time = Clock.now
	
	@last_output_time = nil
	@minimum_output_duration = minimum_output_duration
	
	@current = 0
	@total = total
end

attr :subject

Signature

attribute Object

The subject of the progress indicator.

attr :minimum_output_duration

Signature

attribute Numeric

The minimum duration between outputs.

attr :start_time

Signature

attribute Time

The time the progress indicator was started.

attr :current

Signature

attribute Numeric

The current number of steps completed.

attr :total

Signature

attribute Numeric

The total number of steps.

def duration

Signature

returns Numeric

The duration since the progress indicator was started.

Implementation

def duration
	Clock.now - @start_time
end

def ratio

Signature

returns Rational

The ratio of steps completed to total steps.

Implementation

def ratio
	Rational(@current.to_f, @total.to_f)
end

def remaining

Signature

returns Numeric

The number of steps remaining.

Implementation

def remaining
	@total - @current
end

def average_duration

Signature

returns Numeric | Nil

The average duration per step, or nil if no steps have been completed.

Implementation

def average_duration
	if @current > 0
		duration / @current
	end
end

def estimated_remaining_time

Signature

returns Numeric | Nil

The estimated remaining time, or nil if no steps have been completed.

Implementation

def estimated_remaining_time
	if average_duration = self.average_duration
		average_duration * remaining
	end
end

def to_hash

Generate an appropriate event for the progress indicator.

Signature

returns Hash

The progress indicator as a hash.

Implementation

def to_hash
	Hash.new.tap do |hash|
		hash[:type] = :progress
		hash[:current] = @current
		hash[:total] = @total
		
		hash[:duration] = self.duration
		hash[:estimated_remaining_time] = self.estimated_remaining_time
	end
end

def increment(amount = 1)

Increment the progress indicator by the given amount.

Signature

parameter amount Numeric

The amount to increment by.

returns Progress

The progress indicator itself.

Implementation

def increment(amount = 1)
	@current += amount
	
	if output?
		Console.call(@subject, self.to_s, event: self.to_hash, **@options)
		@last_output_time = Clock.now
	end
	
	return self
end

def resize(total)

Resize the progress indicator to the given total.

Signature

parameter total Numeric

The new total number of steps.

returns Progress

The progress indicator itself.

Implementation

def resize(total)
	@total = total
	
	Console.call(@subject, self.to_s, event: self.to_hash, **@options)
	@last_output_time = Clock.now
	
	return self
end

def mark(*arguments, **options, &block)

Augment the progress indicator with additional information.

Signature

parameter *arguments Array

The arguments to log.

parameter **options Hash

Additional options to log.

parameter &block Proc

An optional block used to generate the log message.

Implementation

def mark(*arguments, **options, &block)
	Console.call(@subject, *arguments, **options, **@options, &block)
end

def to_s

Signature

returns String

A human-readable representation of the progress indicator.

Implementation

def to_s
	if estimated_remaining_time = self.estimated_remaining_time
		"#{@current}/#{@total} completed in #{Clock.formatted_duration(self.duration)}, #{Clock.formatted_duration(estimated_remaining_time)} remaining."
	else
		"#{@current}/#{@total} completed, waiting for estimate..."
	end
end

def duration_since_last_output

Compute a time delta since the last output, used for rate limiting the output.

Signature

returns Numeric | Nil

The duration since the last output.

Implementation

def duration_since_last_output
	if @last_output_time
		Clock.now - @last_output_time
	end
end

def output?

Whether an output should be generated at this time, taking into account the remaining steps, and the duration since the last output.

Signature

returns Boolean

Whether an output should be generated.

Implementation

def output?
	if remaining.zero?
		return true
	elsif duration = duration_since_last_output
		return duration > @minimum_output_duration
	else
		return true
	end
end