# frozen_string_literal: true require_relative "../output/output" require_relative "../logging/logger" require_relative "../helpers/input_output_pair" module Kanal module Core module Helpers class ResponseExecutionBlock include Output include Logging::Logger attr_reader :response_block, :input def initialize(response_block, input, default_error_node, error_node) @response_block = response_block @input = input @default_error_node = default_error_node @error_node = error_node end def execute(core, input_output_pair_queue) if response_block.async? # NOTE: Thread doesnt just die here - it's execution is continued in input_output_pair_queue.enqueue in router # then :item_queued hook is called inside and subsequently output_ready_block gets called in this thread # TODO: be aware that this can cause unexpected behaviour. Maybe think how to rework it. Thread.new do input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core)) end else input_output_pair_queue.enqueue InputOutputPair.new(@input, construct_output(core)) end end private def construct_output(core) logger.debug "Constructing output for input ##{input.__id__}" output = Output::Output.new core.output_parameter_registrator, @input, core begin core.hooks.call :output_just_created, input, output output.instance_eval(&@response_block.block) rescue => e logger.error "Failed to construct output for input ##{input.__id__}. Error: '#{e}'" output = Output::Output.new core.output_parameter_registrator, @input, core error_node = @error_node || @default_error_node logger.debug "Trying to construct error response for input ##{input.__id__}. Error response is default: #{@error_node.nil?}" begin output.instance_eval(&error_node.response_blocks.first.block) rescue => e logger.error "Failed to construct error response for input ##{input.__id__}. Error: '#{e}'" logger.debug "Trying to construct default error response for input ##{input.__id__}" output.instance_eval(&@default_error_node.response_blocks.first.block) end end logger.debug "Output ##{output.__id__} for input ##{input.__id__} constructed" output end end end end end