Class: Roby::ExecutablePlan

Inherits:
Plan show all
Extended by:
Logger::Forward, Logger::Hierarchy
Includes:
ExceptionHandlingObject
Defined in:
lib/roby/executable_plan.rb

Overview

A plan that can be used for execution

While Plan maintains the plan data structure itself, this class provides excution-related services such as exceptions and GC-related methods

Constant Summary

Constants included from GUI::RelationsCanvasPlan

GUI::RelationsCanvasPlan::PLAN_STROKE_WIDTH

Instance Attribute Summary collapse

Attributes inherited from Plan

#active_fault_response_tables, #event_logger, #event_relation_graphs, #free_events, #graph_observer, #local_owner, #mission_tasks, #permanent_events, #permanent_tasks, #plan_services, #structure_checks, #task_events, #task_index, #task_relation_graphs, #tasks, #transactions, #triggers

Attributes included from GUI::RelationsCanvasPlan

#depth, #max_depth

Attributes included from GUI::GraphvizPlan

#depth, #layout_level

Attributes inherited from DistributedObject

#local_owner_id, #owners

Instance Method Summary collapse

Methods included from ExceptionHandlingObject

#add_error, #handle_exception, #pass_exception

Methods inherited from Plan

#[], #add, #add_mission, #add_mission_task, #add_permanent, #add_permanent_event, #add_permanent_task, #add_plan_service, #add_trigger, #added_transaction, #apply_replacement_operations, #apply_triggers_matches, can_gc?, check_failed_missions, #check_structure, #clear!, #compute_subplan_replacement, #compute_useful_free_events, #compute_useful_tasks, #copy_relation_graphs_to, #copy_to, #create_relations, #dedupe, #deep_copy, #deep_copy_to, #default_useful_task_graphs, #dup, #each_event_relation_graph, #each_object_in_transaction_stack, #each_relation_graph, #each_task, #each_task_relation_graph, #edit, #empty?, #event_relation_graph_for, #finalize_event, #finalize_task, #find_all_plan_services, #find_local_tasks, #find_plan_difference, #find_plan_service, #find_tasks, #find_triggers_matches, #force_replace, #force_replace_task, #format_exception_set, #handle_force_replace, #handle_replace, #has_free_event?, #has_task?, #has_task_event?, #in_transaction, #in_useful_subplan?, #include?, #inspect, instanciate_relation_graphs, #local_tasks, #locally_useful_roots, #locally_useful_tasks, #merge, #merge!, #merge_base, #merge_relation_graphs, #merge_transaction!, #mission?, #mission_task?, #move_plan_service, #normalize_add_arguments, #notify_event_status_change, #notify_task_status_change, #num_events, #num_free_events, #num_tasks, #owns?, #permanent?, #permanent_event?, #permanent_task?, #quarantined_tasks, #query_each, #query_result_set, #query_roots, #real_plan, #recreate, #register_event, #register_task, #remote_tasks, #remove_fault_response_table, #remove_free_event, #remove_free_event!, #remove_object, #remove_plan_service, #remove_task!, #remove_transaction, #remove_trigger, #replace, #replace_relation_graphs, #replace_subplan, #replace_task, #replaced, #replan, #root_in_query?, #root_plan?, #same_plan?, #sibling_on?, #size, #static_garbage_collect, #task_relation_graph_for, #template?, #transaction_stack, #unmark_mission, #unmark_mission_task, #unmark_permanent, #unmark_permanent_event, #unmark_permanent_task, #unneeded_events, #unneeded_tasks, #use_fault_response_table, #useful_events, #useful_task?, #useful_tasks, #validate_graphs, #verify_plan_object_finalization_sanity

Methods included from DRoby::V5::PlanDumper

#droby_dump

Methods included from DRoby::Identifiable

#droby_id, #initialize_copy

Methods included from GUI::RelationsCanvasPlan

#display, #display_create, #display_name, #display_parent

Methods included from GUI::GraphvizPlan

#all_events, #apply_layout, #compute_depth, #each_displayed_relation, #each_edge, #each_layout_relation, #layout_relations, #relations_to_dot, #to_dot

Methods included from DRoby::EventLogging

#log, #log_flush_cycle, #log_queue_size, #log_timepoint, #log_timepoint_group, #log_timepoint_group_end, #log_timepoint_group_start

Methods inherited from DistributedObject

#add_owner, #clear_owners, #initialize_copy, #owned_by?, #remove_owner

Constructor Details

#initialize(event_logger: DRoby::NullEventLogger.new) ⇒ ExecutablePlan

Returns a new instance of ExecutablePlan.



43
44
45
46
47
48
49
50
51
52
# File 'lib/roby/executable_plan.rb', line 43

def initialize(event_logger: DRoby::NullEventLogger.new)
    super(graph_observer: self, event_logger: event_logger)

    @execution_engine = ExecutionEngine.new(self)
    @force_gc    = Set.new
    @exception_handlers = Array.new
    on_exception LocalizedError do |plan, error|
        plan.default_localized_error_handling(error)
    end
end

Instance Attribute Details

#connection_spaceObject

The ConnectionSpace object which handles this plan. The role of this object is to sharing with other Roby plan managers



19
20
21
# File 'lib/roby/executable_plan.rb', line 19

def connection_space
  @connection_space
end

#exception_handlersArray<(#===, #call)> (readonly)

The list of plan-wide exception handlers

Returns:

  • (Array<(#===, #call)>)


41
42
43
# File 'lib/roby/executable_plan.rb', line 41

def exception_handlers
  @exception_handlers
end

#execution_engineExecutionEngine

The ExecutionEngine object which handles this plan. The role of this object is to provide the event propagation, error propagation and garbage collection mechanisms for the execution.

Returns:



15
16
17
# File 'lib/roby/executable_plan.rb', line 15

def execution_engine
  @execution_engine
end

#force_gcSet<Roby::Task> (readonly)

A set of tasks which are useful (and as such would not been garbage collected), but we want to GC anyway

Returns:



36
37
38
# File 'lib/roby/executable_plan.rb', line 36

def force_gc
  @force_gc
end

Instance Method Details

#added_edge(parent, child, relations, info) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called after a new edge has been added in this plan

Parameters:

  • parent (Object)

    the child object

  • child (Object)

    the child object

  • relations (Array<Class<Relations::Graph>>)

    the graphs in which an edge has been added

  • info (Object)

    the associated edge info that applies to relations.first



213
214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/roby/executable_plan.rb', line 213

def added_edge(parent, child, relations, info)
    relations.each do |rel|
        if rel == Roby::EventStructure::Precedence
            execution_engine.event_ordering.clear
        end

        if name = rel.child_name
            parent.send("added_#{rel.child_name}", child, info)
            child.send("added_#{rel.child_name}_parent", parent, info)
        end
    end

    log(:added_edge, parent, child, relations, info)
end

#adding_edge(parent, child, relations, info) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called before an edge gets added to this plan

If an exception is raised, the edge will not be added

Parameters:

  • parent (Object)

    the child object

  • child (Object)

    the child object

  • relations (Array<Class<Relations::Graph>>)

    the graphs in which an edge has been added

  • info (Object)

    the associated edge info that applies to relations.first



173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/roby/executable_plan.rb', line 173

def adding_edge(parent, child, relations, info)
    if !parent.read_write? || !child.read_write?
        raise OwnershipError, "cannot remove a relation between two objects we don't own"
    elsif parent.garbage?
        raise ReusingGarbage, "attempting to reuse #{parent} which is marked as garbage"
    elsif child.garbage?
        raise ReusingGarbage, "attempting to reuse #{child} which is marked as garbage"
    end

    if last_dag = relations.find_all(&:dag?).last
        if child.relation_graph_for(last_dag).reachable?(child, parent)
            raise Relations::CycleFoundError, "adding an edge from #{parent} to #{child} would create a cycle in #{last_dag}"
        end
    end

    relations.each do |rel|
        if name = rel.child_name
            parent.send("adding_#{rel.child_name}", child, info)
            child.send("adding_#{rel.child_name}_parent", parent, info)
        end
    end

    for trsc in transactions
        next unless trsc.proxying?
        if (parent_proxy = trsc[parent, create: false]) && (child_proxy = trsc[child, create: false])
            trsc.adding_plan_relation(parent_proxy, child_proxy, relations, info) 
        end
    end
end

#call_structure_check_handler(handler) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called by Roby::ExecutionEngine to verify the plan’s internal structure



542
543
544
545
546
# File 'lib/roby/executable_plan.rb', line 542

def call_structure_check_handler(handler)
    super
rescue Exception => e
    execution_engine.add_framework_error(e, 'structure checking')
end

#clearObject

Clear the plan



525
526
527
528
# File 'lib/roby/executable_plan.rb', line 525

def clear
    super
    @force_gc.clear
end

#controlObject

The DecisionControl object which is associated with this plan. This object’s role is to handle the conflicts that can occur during event propagation.



30
# File 'lib/roby/executable_plan.rb', line 30

def control; execution_engine.control end

#default_localized_error_handling(error) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Default toplevel error handling for LocalizedError

It activates fault handlers, and adds MissionFailedError / PermanentTaskError



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# File 'lib/roby/executable_plan.rb', line 93

def default_localized_error_handling(error)
    matching_handlers = Array.new
    active_fault_response_tables.each do |table|
        table.find_all_matching_handlers(error).each do |handler|
            matching_handlers << [table, handler]
        end
    end
    handlers = matching_handlers.sort_by { |_, handler| handler.priority }

    while !handlers.empty?
        table, handler = handlers.shift
        if handler
            begin
                handler.activate(error, table.arguments)
                return
            rescue Exception => e
                Robot.warn "ignored exception handler #{handler} because of exception"
                Roby.log_exception_with_backtrace(e, Robot, :warn)
            end
        end
    end

    pass_exception
end

#each_exception_handler {|matcher, handler| ... } ⇒ Object

Iterate over the plan-wide exception handlers

Yield Parameters:



494
495
496
# File 'lib/roby/executable_plan.rb', line 494

def each_exception_handler(&block)
    exception_handlers.each(&block)
end

#emit_relation_change_hook(parent, child, rel, *args, prefix: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Helper for #updating_edge_info and #updated_edge_info



307
308
309
310
311
312
# File 'lib/roby/executable_plan.rb', line 307

def emit_relation_change_hook(parent, child, rel, *args, prefix: nil)
    if name = rel.child_name
        parent.send("#{prefix}_#{rel.child_name}", child, *args)
        child.send("#{prefix}_#{rel.child_name}_parent", parent, *args)
    end
end

#emit_relation_graph_merge_hooks(graph, prefix: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Calls the added_* hook methods for all edges in a relation graph

It is a helper for #merged_plan



319
320
321
322
323
324
325
326
327
328
329
# File 'lib/roby/executable_plan.rb', line 319

def emit_relation_graph_merge_hooks(graph, prefix: nil)
    rel = graph.class
    if rel.child_name
        added_child_hook  = "#{prefix}_#{rel.child_name}"
        added_parent_hook = "#{added_child_hook}_parent"
        graph.each_edge do |parent, child, info|
            parent.send(added_child_hook, child, info)
            child.send(added_parent_hook, parent, info)
        end
    end
end

#emit_relation_graph_transaction_application_hooks(list, prefix: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Calls the added_ and adding_ hooks for modifications originating from a transaction that involve tasks originally from the plan



335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
# File 'lib/roby/executable_plan.rb', line 335

def emit_relation_graph_transaction_application_hooks(list, prefix: nil)
    hooks = Hash.new
    list.each do |graph, parent, child, *args|
        if !hooks.has_key?(graph)
            rel = graph.class
            if rel.child_name
                parent_hook = "#{prefix}_#{rel.child_name}"
                child_hook  = "#{parent_hook}_parent"
                hooks[graph] = [parent_hook, child_hook]
            else
                hooks[graph] = nil
            end
        end

        parent_hook, child_hook = hooks[graph]
        next if !child_hook

        parent.send(parent_hook, child, *args)
        child.send(child_hook, parent, *args)
    end
end

#engineObject

Deprecated.

use #execution_engine instead



22
23
24
25
# File 'lib/roby/executable_plan.rb', line 22

def engine
    Roby.warn_deprecated "Plan#engine is deprecated, use #execution_engine instead"
    execution_engine
end

#event_logger=(logger) ⇒ Object



82
83
84
85
# File 'lib/roby/executable_plan.rb', line 82

def event_logger=(logger)
    super
    log :register_executable_plan, droby_id
end

#executable?Boolean

Check that this is an executable plan

This always returns true for Roby::ExecutablePlan

Returns:

  • (Boolean)


75
# File 'lib/roby/executable_plan.rb', line 75

def executable?; true end

#execute(&block) ⇒ Object

Calls the given block in the execution thread of this plan’s engine. If there is no engine attached to this plan, yields immediately

See ExecutionEngine#execute



141
142
143
# File 'lib/roby/executable_plan.rb', line 141

def execute(&block)
    execution_engine.execute(&block)
end

#finalized_event(event) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called when an event is finalized



156
157
158
159
# File 'lib/roby/executable_plan.rb', line 156

def finalized_event(event)
    execution_engine.finalized_event(event)
    super
end

#finalized_task(task) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called when a task is finalized



148
149
150
151
# File 'lib/roby/executable_plan.rb', line 148

def finalized_task(task)
    execution_engine.finalized_task(task)
    super
end

#garbage_event(event) ⇒ Boolean

Called to handle a free event that should be garbage-collected

What actually happens to the event is controlled by PlanObject#can_finalize?. If the event can be finalized, it is (i.e. removed from the plan, after having triggered all relevant log events/hooks). Otherwise, its relations are cleared and the task is left in the plan

Returns:

  • (Boolean)

    true if the plan got modified, and false otherwise. In practice, it will return false only for events that had no relations and that cannot be finalized.



476
477
478
479
480
481
482
483
484
# File 'lib/roby/executable_plan.rb', line 476

def garbage_event(event)
    log(:garbage_event, droby_id, event)
    if event.can_finalize?
        remove_free_event(event)
        true
    else
        event.clear_relations(remove_strong: false)
    end
end

#garbage_task(task) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Called to handle a task that should be garbage-collected

What actually happens to the task is controlled by PlanObject#can_finalize?.

If the task can be finalized, it is removed from the plan, after having triggered all relevant log events/hooks.

Otherwise, it is isolated from the rest of the plan. Its relations and the relations of its events are cleared and the task is left in the plan. In the latter case, the task is marked as non-reusable.

Always check Task#reusable? before using a task present in an Roby::ExecutablePlan in a new structure.

Parameters:

  • task (Task)

    the task that is being garbage-collected

Returns:

  • (Boolean)

    true if the plan got modified, and false otherwise. In practice, it will return false only if the task cannot be finalized and has external relations.



453
454
455
456
457
458
459
460
461
462
463
# File 'lib/roby/executable_plan.rb', line 453

def garbage_task(task)
    log(:garbage_task, droby_id, task, task.can_finalize?)

    if task.can_finalize?
        remove_task(task)
        true
    else
        task.garbage!
        task.clear_relations(remove_internal: false, remove_strong: false)
    end
end

#generate_induced_errors(error_phase_results) ⇒ Object



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/roby/executable_plan.rb', line 118

def generate_induced_errors(error_phase_results)
    error_phase_results.each_fatal_error do |execution_exception, tasks|
        # MissionFailedError and PermanentTaskError are not propagated,
        # so tasks == [origin] and we should not re-add an error
        if execution_exception.exception.kind_of?(MissionFailedError) ||
                execution_exception.exception.kind_of?(PermanentTaskError)
            next
        end

        tasks.each do |t|
            if mission_task?(t)
                add_error(MissionFailedError.new(t, execution_exception.exception), propagate_through: [])
            elsif permanent_task?(t)
                add_error(PermanentTaskError.new(t, execution_exception.exception), propagate_through: [])
            end
        end
    end
end

#merge_transaction(transaction, merged_graphs, added, removed, updated) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Applies modification information extracted from a transaction. This is used by Transaction#commit_transaction



361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/roby/executable_plan.rb', line 361

def merge_transaction(transaction, merged_graphs, added, removed, updated)
    added.each do |_, parent, child, _|
        if parent.garbage?
            raise ReusingGarbage, "attempting to reuse #{parent} which is marked as garbage"
        elsif child.garbage?
            raise ReusingGarbage, "attempting to reuse #{child} which is marked as garbage"
        end
    end

    emit_relation_graph_transaction_application_hooks(added, prefix: 'adding')
    emit_relation_graph_transaction_application_hooks(removed, prefix: 'removing')
    emit_relation_graph_transaction_application_hooks(updated, prefix: 'updating')

    super

    precedence_graph = event_relation_graph_for(EventStructure::Precedence)
    precedence_edge_count = precedence_graph.num_edges
    emit_relation_graph_transaction_application_hooks(added, prefix: 'added')
    if precedence_edge_count != precedence_graph.num_edges
        execution_engine.event_ordering.clear
    end
    emit_relation_graph_transaction_application_hooks(removed, prefix: 'removed')
    if precedence_edge_count != precedence_graph.num_edges
        execution_engine.event_ordering.clear
    end
    emit_relation_graph_transaction_application_hooks(updated, prefix: 'updated')

    added.each do |graph, parent, child, info|
        log(:added_edge, parent, child, [graph.class], info)
    end
    removed.each do |graph, parent, child|
        log(:removed_edge, parent, child, [graph.class])
    end
    updated.each do |graph, parent, child, info|
        log(:updated_edge_info, parent, child, graph.class, info)
    end
end

#merged_plan(plan) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits the added_* hooks when a plan gets merged in self



415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
# File 'lib/roby/executable_plan.rb', line 415

def merged_plan(plan)
    if !plan.event_relation_graph_for(EventStructure::Precedence).empty?
        execution_engine.event_ordering.clear
    end

    plan.each_task_relation_graph do |graph|
        emit_relation_graph_merge_hooks(graph, prefix: 'added')
    end
    plan.each_event_relation_graph do |graph|
        emit_relation_graph_merge_hooks(graph, prefix: 'added')
    end

    super

    log(:merged_plan, droby_id, plan)
end

#merging_plan(plan) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Emits the adding_* hooks when a plan gets merged in self



402
403
404
405
406
407
408
409
410
# File 'lib/roby/executable_plan.rb', line 402

def merging_plan(plan)
    plan.each_task_relation_graph do |graph|
        emit_relation_graph_merge_hooks(graph, prefix: 'adding')
    end
    plan.each_event_relation_graph do |graph|
        emit_relation_graph_merge_hooks(graph, prefix: 'adding')
    end
    super
end

#on_exception(matcher) {|plan, exception| ... } ⇒ Object

Register a new exception handler

Parameters:

  • matcher (#===, #to_execution_exception_matcher)

    an object that matches exceptions for which the handler should be called. Exception classes can be used directly. If more advanced matching is needed, use .match to convert an exception class into Queries::LocalizedErrorMatcher or one of its subclasses.

Yield Parameters:



509
510
511
512
# File 'lib/roby/executable_plan.rb', line 509

def on_exception(matcher, &handler)
    check_arity(handler, 2)
    exception_handlers.unshift [matcher.to_execution_exception_matcher, handler]
end

#quarantine_task(task) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Put the given task in quarantine. In practice, it means that all the event relations of that task’s events are removed, as well as its children. Then, the task is marked as quarantined with Task#quarantined? and the engine will not attempt to garbage-collect it anymore

This is used as a last resort, when the task cannot be stopped/GCed by normal means.



64
65
66
67
68
69
70
# File 'lib/roby/executable_plan.rb', line 64

def quarantine_task(task)
    log(:quarantined_task, droby_id, task)

    task.quarantined!
    task.clear_relations(remove_internal: false, remove_strong: false)
    self
end

#refresh_relationsObject



77
78
79
80
# File 'lib/roby/executable_plan.rb', line 77

def refresh_relations
    super
    execution_engine.refresh_relations
end

#remove_task(object, timestamp = nil) ⇒ Object

Actually remove a task from the plan



515
516
517
518
519
520
521
522
# File 'lib/roby/executable_plan.rb', line 515

def remove_task(object, timestamp = nil)
    if object.respond_to?(:running?) && object.running? && object.self_owned?
        raise ArgumentError, "attempting to remove #{object}, which is a running task, from an executable plan"
    end

    super
    @force_gc.delete(object)
end

#removed_edge(parent, child, relations) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called after an edge has been removed from this plan

Parameters:

  • parent (Object)

    the child object

  • child (Object)

    the child object

  • relations (Array<Class<Relations::Graph>>)

    the graphs in which an edge has been removed



293
294
295
296
297
298
299
300
301
302
# File 'lib/roby/executable_plan.rb', line 293

def removed_edge(parent, child, relations)
    relations.each do |rel|
        if name = rel.child_name
            parent.send("removed_#{rel.child_name}", child)
            child.send("removed_#{rel.child_name}_parent", parent)
        end
    end

    log(:removed_edge, parent, child, relations)
end

#removing_edge(parent, child, relations) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called before an edge gets removed from this plan

If an exception is raised, the edge will not be removed

Parameters:

  • parent (Object)

    the parent object

  • child (Object)

    the child object

  • relations (Array<Class<Relations::Graph>>)

    the graphs in which an edge is being removed



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/roby/executable_plan.rb', line 265

def removing_edge(parent, child, relations)
    unless parent.read_write? || child.child.read_write?
        raise OwnershipError, "cannot remove a relation between two objects we don't own"
    end

    relations.each do |rel|
        if name = rel.child_name
            parent.send("removing_#{rel.child_name}", child)
            child.send("removing_#{rel.child_name}_parent", parent)
        end
    end

    for trsc in transactions
        next unless trsc.proxying?
        if (parent_proxy = trsc[parent, create: false]) && (child_proxy = trsc[child, create: false])
            trsc.removing_plan_relation(parent_proxy, child_proxy, relations) 
        end
    end
end

#respawn(task) ⇒ Object

Replace task with a fresh copy of itself and start it.

See #recreate for details about the new task.



533
534
535
536
537
# File 'lib/roby/executable_plan.rb', line 533

def respawn(task)
    new = recreate(task)
    execution_engine.once { new.start!(nil) }
    new
end

#updated_edge_info(parent, child, relation, info) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called when the edge information of an existing edge has been updated

Parameters:

  • parent

    the edge parent object

  • child

    the edge child object

  • relation (Class<Relations::Graph>)

    the relation graph ID

  • info (Object)

    the new edge info



250
251
252
253
# File 'lib/roby/executable_plan.rb', line 250

def updated_edge_info(parent, child, relation, info)
    emit_relation_change_hook(parent, child, relation, info, prefix: 'updated')
    log(:updated_edge_info, parent, child, relation, info)
end

#updating_edge_info(parent, child, relation, info) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Hook called to announce that the edge information of an existing edge will be updated

Parameters:

  • parent

    the edge parent object

  • child

    the edge child object

  • relation (Class<Relations::Graph>)

    the relation graph ID

  • info (Object)

    the new edge info



237
238
239
# File 'lib/roby/executable_plan.rb', line 237

def updating_edge_info(parent, child, relation, info)
    emit_relation_change_hook(parent, child, relation, info, prefix: 'updating')
end