Class: Roby::Schedulers::Basic
- Defined in:
- lib/roby/schedulers/basic.rb
Overview
The basic schedulers uses the Roby’s “core” plan model to decide which tasks can be started.
See the documentation of Roby::Schedulers for more information
The basic scheduler starts the tasks for which:
* the task is pending, executable and owned by the local robot
* the start event is root in all event relations (i.e. there is
neither signals and forwards pointing to it).
* it is root in the dependency relationship
* if the +include_children+ option of Basic.new is set to true, it
may be non-root in the dependency relation, in which case it is
started if and only if it has at least one parent that is running
(i.e. children are started after their parents).
Direct Known Subclasses
Instance Attribute Summary collapse
-
#include_children ⇒ Object
readonly
If true, the scheduler will start tasks which are non-root in the dependency relation, if they have parents that are already running.
-
#plan ⇒ Object
readonly
The plan on which the scheduler applies.
-
#query ⇒ Object
readonly
The Roby::Query which is used to get the set of tasks that might be startable.
Instance Method Summary collapse
- #basic_scheduling_root_task?(task) ⇒ Boolean
- #can_schedule?(task, time = Time.now, stack = []) ⇒ Boolean
- #can_start?(task) ⇒ Boolean
-
#initial_events ⇒ Object
Starts all tasks that are eligible.
-
#initialize(include_children = false, plan = nil) ⇒ Basic
constructor
Create a new Basic schedulers that work on the given plan, and with the provided
include_children
option.
Methods inherited from Reporting
#report_action, #report_holdoff, #report_pending_non_executable_task, #report_trigger
Constructor Details
#initialize(include_children = false, plan = nil) ⇒ Basic
Create a new Basic schedulers that work on the given plan, and with the provided include_children
option.
See Basic for a description of the include_children
option.
If plan
is set to nil, the scheduler will use Roby.plan
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/roby/schedulers/basic.rb', line 55 def initialize(include_children = false, plan = nil) super() @plan = plan || Roby.plan @include_children = include_children @query = self.plan.find_tasks .executable .pending .self_owned @enabled = true end |
Instance Attribute Details
#include_children ⇒ Object (readonly)
If true, the scheduler will start tasks which are non-root in the dependency relation, if they have parents that are already running.
47 48 49 |
# File 'lib/roby/schedulers/basic.rb', line 47 def include_children @include_children end |
#plan ⇒ Object (readonly)
The plan on which the scheduler applies
40 41 42 |
# File 'lib/roby/schedulers/basic.rb', line 40 def plan @plan end |
#query ⇒ Object (readonly)
The Roby::Query which is used to get the set of tasks that might be startable
43 44 45 |
# File 'lib/roby/schedulers/basic.rb', line 43 def query @query end |
Instance Method Details
#basic_scheduling_root_task?(task) ⇒ Boolean
116 117 118 119 120 121 122 |
# File 'lib/roby/schedulers/basic.rb', line 116 def basic_scheduling_root_task?(task) return true if task.root?(TaskStructure::Dependency) planned_tasks = task.planned_tasks !planned_tasks.empty? && planned_tasks.all? { |t| !t.executable? } end |
#can_schedule?(task, time = Time.now, stack = []) ⇒ Boolean
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/roby/schedulers/basic.rb', line 96 def can_schedule?(task, time = Time.now, stack = []) unless can_start?(task) report_holdoff "cannot be started", task return false end root_task = basic_scheduling_root_task?(task) if root_task true elsif include_children && task.parents.any?(&:running?) 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 |
#can_start?(task) ⇒ Boolean
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/roby/schedulers/basic.rb', line 70 def can_start?(task) start_event = task.start_event unless start_event.controlable? report_holdoff "start event not controlable", task return false end if (agent = task.execution_agent) && !agent.ready_event.emitted? report_holdoff "task's execution agent %2 is not ready", task, agent return false end unless start_event.root?(EventStructure::CausalLink) report_holdoff "start event not root in the causal link relation", task return false end task.each_relation do |r| if r.respond_to?(:scheduling?) && !r.scheduling? && !task.root?(r) report_holdoff "not root in %2, which forbids scheduling", task, r return false end end true end |
#initial_events ⇒ Object
Starts all tasks that are eligible. See the documentation of the Basic class for an in-depth description
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# File 'lib/roby/schedulers/basic.rb', line 126 def initial_events time = Time.now not_executable = self.plan.find_tasks .not_executable .pending .self_owned not_executable.each do |task| # Try to figure out why ... if task.execution_agent && !task.execution_agent.ready? report_pending_non_executable_task("execution agent not ready (%2)", task, task.execution_agent) elsif task.partially_instanciated? report_pending_non_executable_task("partially instanciated", task) else report_pending_non_executable_task("not executable", task) end end scheduled_tasks = [] for task in query.reset if can_schedule?(task, time, []) task.start! report_trigger task.start_event scheduled_tasks << task end end scheduled_tasks end |