Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
uoy-faculty-datasync / lib / datasync / sync_runner.rb
Size: Mime:
# frozen_string_literal: true

require 'delegate'
require 'time'

# Delegator to provide sequencing and reporting
class SyncRunner < SimpleDelegator
  attr_reader :terminating_exception

  def ok?
    !aborted? && errors.empty?
  end

  def aborted?
    @terminating_exception ? true : false
  end

  def profile(name)
    @timing ||= {}
    @timing[name] = t = { start: Time.now }
    yield
  ensure
    t[:end] = Time.now
    t[:duration] = t[:end] - t[:start]
  end

  def runtime
    @timing[:total][:duration]
  end

  def run!
    profile(:total) { run_tasks }
  rescue StandardError => e
    @terminating_exception = e
  end

  def run_tasks
    profile(:load_data) { load_data }
    profile(:classify_links) { classify_links }
    profile(:do_match) { do_match }
    check_limits!
    profile(:handle_actions) { handle_actions }
    unload_data
  end

  def report
    @report = []
    append "Sync '#{mapper.title}' started at #{@timing[:total][:start].iso8601}"

    report_totals
    report_errors
    report_exception
    report_timing_information

    append "Sync '#{mapper.title}' ended at #{@timing[:total][:end].iso8601}"
    @report
  end

  private

  def append(*lines)
    @report += lines.flatten
  end

  def report_totals
    append 'Totals:'
    totals.each { |name, value| append "  #{name}: #{value}" if value.positive? }
    append "Dropped updates: #{dropped_updates}"
  end

  def report_errors
    return if ok?

    append 'The following errors occurred during the operation:'
    append errors.map(&method(:error_report_string))
  end

  def report_exception
    return unless aborted?

    append "The sync terminated prematurely because of a #{@terminating_exception.class}"
    append "  #{@terminating_exception}"
    @terminating_exception.backtrace&.each do |line|
      append "    #{line}"
    end
  end

  def report_timing_information
    append 'Timing information:'
    @timing.each do |name, t|
      append format('  %<name>s: %<time>.1f seconds', name: name, time: t[:duration])
    end
  end

  def error_report_string(error)
    e = error
    context = "Error processing #{e[:situation]} #{e[:source_id]}:#{e[:target_id]}"
    issue = "#{e[:error]}: #{e[:message]}"
    "#{context}: #{issue}"
  end
end