class UltraMarathon::BaseRunner

Constants

RUN_INSTRUMENTATION_NAME

Attributes

success[RW]

Public Class Methods

new(*args, &block) click to toggle source

Public Class Methods

Calls superclass method
# File lib/ultra_marathon/base_runner.rb, line 21
def self.new(*args, &block)
  super(*args, &block).tap do |instance|
    instance.send(:invoke_after_initialize_callbacks)
  end
end

Public Instance Methods

reset() click to toggle source

Resets success to being true, unsets the failed sub_runners to [], and sets the unrun sub_runners to be the uncompleted/failed ones

# File lib/ultra_marathon/base_runner.rb, line 54
def reset
  reset_failed_runners
  @success = nil
  invoke_on_reset_callbacks
  self
end
run!() click to toggle source

Runs the run block safely in the context of the instance

# File lib/ultra_marathon/base_runner.rb, line 30
def run!
  if unrun_sub_runners.any?
    instrument RUN_INSTRUMENTATION_NAME do
      begin
        self.success = nil
        invoke_before_run_callbacks
        instrument(:__run_unrun_sub_runners) { run_unrun_sub_runners }
        # If any of the sub runners explicitly set the success flag, don't override it
        self.success = failed_sub_runners.empty? if self.success.nil?
      rescue StandardError => error
        invoke_on_error_callbacks(error)
      end
    end
    invoke_after_run_callbacks
  end
  self
end
run_instrumentation() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 61
def run_instrumentation
  instrumentations[RUN_INSTRUMENTATION_NAME]
end
success?() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 48
def success?
  !!success
end

Private Instance Methods

clean_up_completed_sub_runners() click to toggle source

Cleans up all dead threads, settings

# File lib/ultra_marathon/base_runner.rb, line 88
def clean_up_completed_sub_runners
  completed_runners, unfinished_runners = running_sub_runners.partition(&:complete?)
  completed_runners.each do |sub_runner|
    clean_up_sub_runner(sub_runner)
  end
  self.running_sub_runners = unfinished_runners
end
clean_up_sub_runner(sub_runner) click to toggle source

Adds a run sub runner to the appropriate sub runner store based on its success or failure and removes it from the unrun_sub_runners Also merges its instrumentation to the group's instrumentation

# File lib/ultra_marathon/base_runner.rb, line 99
def clean_up_sub_runner(sub_runner)
  if sub_runner.success
    successful_sub_runners << sub_runner
  else
    failed_sub_runners << sub_runner
  end
  instrumentations.merge!(sub_runner.instrumentations)
  unrun_sub_runners.delete sub_runner.name
end
complete?() click to toggle source

TODO: timeout option

# File lib/ultra_marathon/base_runner.rb, line 110
def complete?
  running_sub_runners.empty? && unrun_sub_runners.empty?
end
log_all_sub_runners() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 137
def log_all_sub_runners
  log_failed_sub_runners if failed_sub_runners.any?
  log_successful_sub_runners if successful_sub_runners.any?
end
log_failed_sub_runners() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 142
def log_failed_sub_runners
  logger.info """

  == Failed SubRunners ==

  """
  log_sub_runners(failed_sub_runners)
end
log_sub_runners(sub_runners) click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 161
def log_sub_runners(sub_runners)
  sub_runners.each do |sub_runner|
    logger.info(sub_runner.logger.contents << "\n")
  end
end
log_successful_sub_runners() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 151
def log_successful_sub_runners
  logger.info """

  == Successful SubRunners ==

  """
  log_sub_runners(successful_sub_runners)
end
log_summary() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 167
def log_summary
  run_profile = instrumentations[:run!]
  failed_names = failed_sub_runners.names.map(&:to_s).join(', ')
  succcessful_names = successful_sub_runners.names.map(&:to_s).join(', ')
  unrun_names = unrun_sub_runners.names.map(&:to_s).join(', ')
  logger.info """

  Status: #{status}

  Failed (#{failed_sub_runners.size}): #{failed_names}
  Successful (#{successful_sub_runners.size}): #{succcessful_names}
  Unrun (#{unrun_sub_runners.size}): #{unrun_names}

  #{time_summary}

  """
end
reset_failed_runners() click to toggle source

Resets all failed sub runners, then sets them as unrun_sub_runners and failed_sub_runners to an empty Store

# File lib/ultra_marathon/base_runner.rb, line 116
def reset_failed_runners
  failed_sub_runners.each(&:reset)
  @unrun_sub_runners = failed_sub_runners
  @failed_sub_runners = Store.new
end
run_unrun_sub_runners() click to toggle source

If all of the parents have been successfully run (or there are no parents), runs the sub_runner. If any one of the parents has failed, considers the runner a failure If some parents have not yet completed, carries on

# File lib/ultra_marathon/base_runner.rb, line 73
def run_unrun_sub_runners
  until complete?
    unrun_sub_runners.each do |sub_runner|
      if sub_runner_can_run? sub_runner
        running_sub_runners << sub_runner.run!
      elsif sub_runner.parents.any? { |name| failed_sub_runners.exists? name }
        failed_sub_runners << sub_runner
        unrun_sub_runners.delete sub_runner.name
      end
    end
    clean_up_completed_sub_runners
  end
end
status() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 129
def status
  if success?
    'Success'
  else
    'Failure'
  end
end
sub_runner_can_run?(sub_runner) click to toggle source

A sub runner can run if all prerequisites have been satisfied. This means all parent runners - those specified by name using the :requires options - have successfully completed.

# File lib/ultra_marathon/base_runner.rb, line 125
def sub_runner_can_run?(sub_runner)
  successful_sub_runners.includes_all?(sub_runner.parents)
end
sub_runner_instrumentations() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 185
def sub_runner_instrumentations
  @sub_runner_instrumentations ||= begin
    sub_runner_profiles = instrumentations.select do |profile|
      profile.name.to_s.start_with? 'sub_runner.'
    end
    UltraMarathon::Instrumentation::Store.new(sub_runner_profiles)
  end
end
sub_runner_summary() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 204
def sub_runner_summary
  median_profile = sub_runner_instrumentations.median
  max_profile = sub_runner_instrumentations.max
  min_profile = sub_runner_instrumentations.min
  """
  Max SubRunner Runtime: #{max_profile.name} (#{max_profile.total_time})
  Min SubRunner Runtime: #{min_profile.name} (#{min_profile.total_time})
  Median SubRunner Runtime: #{median_profile.name} (#{median_profile.total_time})
  SubRunner Runtime Standard Deviation: #{sub_runner_instrumentations.standard_deviation}
  """
end
time_summary() click to toggle source
# File lib/ultra_marathon/base_runner.rb, line 194
def time_summary
  """
  Run Start Time: #{run_instrumentation.formatted_start_time}
  End Time: #{run_instrumentation.formatted_end_time}
  Total Time: #{run_instrumentation.formatted_total_time}

  #{sub_runner_summary if sub_runner_instrumentations.any?}
  """
end