module Roby::Coordination::Models::FaultHandler

Definition of a single fault handler in a FaultResponseTable

Public Instance Methods

activate(exception, arguments = Hash.new) click to toggle source

@api private

Activate this fault handler for the given exception and arguments. It creates the {FaultHandlingTask} and attaches the handler on it as an action script.

@param [ExecutionException] exception @param [Hash] arguments

# File lib/roby/coordination/models/fault_handler.rb, line 183
def activate(exception, arguments = Hash.new)
    locations = find_response_locations(exception.origin)
    if locations.empty?
        Roby.warn "#{self} did match an exception, but the response location #{response_location} does not match anything"
        return
    end

    plan = exception.origin.plan

    # Create the response task
    plan.add(response_task = FaultHandlingTask.new)
    response_task.fault_handler = self
    new(response_task, arguments)
    response_task.start!
    locations.each do |task|
        # Mark :stop as handled by the response task and kill
        # the task
        #
        # In addition, if origin == task, we need to handle the
        # error events as well
        task.add_error_handler response_task,
            [task.stop_event.to_execution_exception_matcher, execution_exception_matcher].to_set
    end
    locations.each do |task|
        # This should not be needed. However, the current GC
        # implementation in ExecutionEngine does not stop at
        # finished tasks, and therefore would not GC the
        # underlying tasks
        task.remove_children(Roby::TaskStructure::Dependency)
        task.stop! if task.running?
    end
end
carry_on() click to toggle source

Try the repaired action again when the fault handler successfully finishes

It can be called anytime in the script, but will have an effect only at the end of the fault handler

# File lib/roby/coordination/models/fault_handler.rb, line 57
def carry_on
    __carry_on(true)
    terminal
end
carry_on?() click to toggle source

@return [Boolean] if true, the last action of the response

will be to retry whichever action/missions/tasks have been
interrupted by the fault
# File lib/roby/coordination/models/fault_handler.rb, line 26
def carry_on?; !!__carry_on end
fault_response_table() click to toggle source

@return [FaultResponseTable] the table this handler is part of

# File lib/roby/coordination/models/fault_handler.rb, line 10
def fault_response_table; action_interface end
find_response_locations(origin) click to toggle source
# File lib/roby/coordination/models/fault_handler.rb, line 155
def find_response_locations(origin)
    if response_location == :origin
        return [origin].to_set
    end

    predicate =
        if response_location == :missions
            proc { |t| t.mission? && t.running? }
        elsif response_location == :actions
            proc { |t| t.running? && t.planning_task && t.planning_task.kind_of?(Roby::Actions::Task) }
        end

    search_graph = origin.plan.
        task_relation_graph_for(TaskStructure::Dependency).
        reverse
    visitor = ResponseLocationVisitor.new(search_graph, predicate)
    search_graph.depth_first_visit(origin, visitor) {}
    visitor.selected
end
locate_on_actions() click to toggle source
# File lib/roby/coordination/models/fault_handler.rb, line 42
def locate_on_actions
    response_location :actions
    self
end
locate_on_missions() click to toggle source
# File lib/roby/coordination/models/fault_handler.rb, line 37
def locate_on_missions
    response_location :missions
    self
end
locate_on_origin() click to toggle source
# File lib/roby/coordination/models/fault_handler.rb, line 47
def locate_on_origin
    response_location :origin
    self
end
replace_by(task, until_event = nil) click to toggle source

Replace the response's location by this task when the fault handler script is finished

It terminates the script, i.e. no instructions can be added after it is called

@raise ArgumentError if there is already a replacement task

# File lib/roby/coordination/models/fault_handler.rb, line 121
def replace_by(task, until_event = nil)
    __carry_on(false)
    replacement_task = validate_or_create_task(task)
    start replacement_task
    instructions << ReplaceBy.new(replacement_task)
    wait(until_event || replacement_task.success_event)
    instructions << FinalizeReplacement.new
    emit success_event
    terminal
end
to_s() click to toggle source
# File lib/roby/coordination/models/fault_handler.rb, line 33
def to_s
    "#{fault_response_table}.on_fault(#{execution_exception_matcher})"
end
try_again() click to toggle source

@deprecated use {#carry_on}

# File lib/roby/coordination/models/fault_handler.rb, line 63
def try_again; carry_on end
try_again?() click to toggle source

@deprecated use {#carry_on?}

# File lib/roby/coordination/models/fault_handler.rb, line 28
def try_again?; carry_on? end