Class: Roby::Schedulers::Temporal
- Defined in:
- lib/roby/schedulers/temporal.rb
Overview
The temporal scheduler adds to the decisions made by the Basic scheduler information given by the temporal constraint network.
See the documentation of Roby::Schedulers for more information
Instance Attribute Summary collapse
-
#scheduling_constraints_graph ⇒ Object
readonly
The proper graph object that contains the scheduling constraints.
Attributes inherited from Basic
#include_children, #plan, #query
Instance Method Summary collapse
- #can_schedule?(task, time = Time.now, stack = []) ⇒ Boolean
-
#initialize(with_basic = true, with_children = true, plan = nil) ⇒ Temporal
constructor
A new instance of Temporal.
- #parent_waiting_for_self?(task, parent_task) ⇒ Boolean
- #parents_allow_scheduling?(task, time, stack) ⇒ Boolean
- #verify_schedule_as_constraints(task, time, stack) ⇒ Object
- #verify_temporal_constraints(task, time, stack) ⇒ Object
Methods inherited from Basic
#basic_scheduling_root_task?, #can_start?, #initial_events
Methods inherited from Reporting
#report_action, #report_holdoff, #report_pending_non_executable_task, #report_trigger
Constructor Details
#initialize(with_basic = true, with_children = true, plan = nil) ⇒ Temporal
Returns a new instance of Temporal.
19 20 21 22 23 24 |
# File 'lib/roby/schedulers/temporal.rb', line 19 def initialize(with_basic = true, with_children = true, plan = nil) super(with_children, plan) @basic_constraints = with_basic @scheduling_constraints_graph = self.plan .event_relation_graph_for(EventStructure::SchedulingConstraints) end |
Instance Attribute Details
#scheduling_constraints_graph ⇒ Object (readonly)
The proper graph object that contains the scheduling constraints
17 18 19 |
# File 'lib/roby/schedulers/temporal.rb', line 17 def scheduling_constraints_graph @scheduling_constraints_graph end |
Instance Method Details
#can_schedule?(task, time = Time.now, stack = []) ⇒ Boolean
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/roby/schedulers/temporal.rb', line 26 def can_schedule?(task, time = Time.now, stack = []) if task.running? return true elsif !can_start?(task) report_holdoff "cannot be started", task return false end return false unless verify_temporal_constraints(task, time, stack) return false unless verify_schedule_as_constraints(task, time, stack) return true unless basic_constraints? root_task = basic_scheduling_root_task?(task) if root_task true elsif include_children && parents_allow_scheduling?(task, time, stack) true elsif include_children report_holdoff "not root, and has no running parent", task false else report_holdoff "not root, and include_children is false", task false end end |
#parent_waiting_for_self?(task, parent_task) ⇒ Boolean
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/roby/schedulers/temporal.rb', line 106 def parent_waiting_for_self?(task, parent_task) # Special case: check in Dependency if there are some # parents for which a forward constraint from +self+ to # +parent.start_event+ exists. If it is the case, start # the task parent_task.start_event.each_backward_temporal_constraint do |constraint| if constraint.respond_to?(:task) && constraint.task == task Schedulers.debug do "Temporal: #{task} has no running parent, but " \ "a constraint from #{constraint} to #{parent_task}.start " \ "exists. Scheduling." end return true end end false end |
#parents_allow_scheduling?(task, time, stack) ⇒ Boolean
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/roby/schedulers/temporal.rb', line 81 def parents_allow_scheduling?(task, time, stack) task.each_parent_task.any? do |parent_task| next(true) if parent_task.running? parent_waiting_for_self = parent_waiting_for_self?(task, parent_task) parent_scheduled_as_self = task.start_event.child_object?( parent_task.start_event, Roby::EventStructure::SchedulingConstraints ) next(false) unless parent_scheduled_as_self || parent_waiting_for_self next(true) if stack.include?(parent_task) begin stack.push task can_schedule?(parent_task, time, stack) ensure stack.pop end end end |
#verify_schedule_as_constraints(task, time, stack) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/roby/schedulers/temporal.rb', line 52 def verify_schedule_as_constraints(task, time, stack) # "backward scheduling constraint" == "schedule_as", # that is in this loop, start_event.schedule_as(parent.start_event) task.start_event .each_backward_scheduling_constraint do |scheduled_as_event| scheduled_as_task = scheduled_as_event.task next if stack.include?(scheduled_as_task) if !scheduled_as_task.executable? && task.depends_on?(scheduled_as_task) return false end begin stack.push task unless can_schedule?(scheduled_as_task, time, stack) report_holdoff( "held by schedule_as(%2)", task, scheduled_as_event ) return false end ensure stack.pop end end true end |
#verify_temporal_constraints(task, time, stack) ⇒ Object
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/roby/schedulers/temporal.rb', line 125 def verify_temporal_constraints(task, time, stack) event_filter = lambda do |ev| if ev.respond_to?(:task) ev.task != task && !stack.include?(ev.task) && !scheduling_constraints_graph.(ev.task, task) else true end end start_event = task.start_event if (failed_temporal = start_event.find_failed_temporal_constraint(time, &event_filter)) report_holdoff "temporal constraints not met (%2: %3)", task, failed_temporal[0], failed_temporal[1] return false elsif (failed_occurence = start_event.find_failed_occurence_constraint(true, &event_filter)) report_holdoff "occurence constraints not met (%2)", task, failed_occurence return false end true end |