lib/production_run.rb
76 lines · ruby
Project files
# frozen_string_literal: true
require_relative "batch_record"
require_relative "halted_run"
require_relative "run_result"
require_relative "work_in_progress"
class ProductionRun
def initialize(classifier:, gate:, line:, final_inspection:)
@classifier = classifier
@gate = gate
@press = line.press
@recovery = line.recovery
@final_inspection = final_inspection
end
def call(items, provenance:)
classification = @classifier.classify(items)
admitted, rejected = partition_admissions(classification.accepted)
execute(admitted, classification, rejected, provenance)
end
private
def execute(admitted, classification, rejected, provenance)
fault = run_through_press(admitted)
return halted_result(fault, classification, rejected) if fault
completed_result(classification, rejected, provenance)
end
def partition_admissions(cases)
assessed = cases.map { |kase| [kase, @gate.assess(kase)] }
admitted = assessed.select { |_, admission| admission.admitted? }.map(&:first)
[admitted, assessed.reject { |_, admission| admission.admitted? }]
end
def run_through_press(cases)
queue = cases.map { |kase| WorkInProgress.new(cartridge_case: kase) }
until queue.empty? && @press.empty?
cycle = run_cycle(queue)
return cycle unless cycle.advanced?
end
end
def run_cycle(queue)
@press.feed(queue.shift) unless queue.empty?
@press.cycle
end
def inspect_completed
assessed = @press.completed.map { |work| [work, @final_inspection.assess(work)] }
released = assessed.select { |_, admission| admission.admitted? }.map(&:first)
[released, assessed.reject { |_, admission| admission.admitted? }]
end
def record_for(released, provenance)
BatchRecord.new(cartridge_count: released.length, **provenance)
end
def completed_result(classification, rejected, provenance)
released, quarantined = inspect_completed
RunResult.new(released: released, record: record_for(released, provenance),
wrong_context: classification.wrong_context,
foreign: classification.foreign,
rejected: rejected, quarantined: quarantined)
end
def halted_result(cycle, classification, rejected)
positions = @press.positions
HaltedRun.new(faults: cycle.outcomes.select { |outcome| outcome.status == :faulted },
positions: positions, recovery_plan: @recovery.assess(positions),
wrong_context: classification.wrong_context,
foreign: classification.foreign, rejected: rejected)
end
end
Read along in the manual: The Reloading Lab · Download the project (zip)