Repository URL to install this package:
|
Version:
0.4.4 ▾
|
# 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