Module: Roby
- Extended by:
- Logger::Forward, Logger::Hierarchy, ExceptionHandlingObject
- Included in:
- Test
- Defined in:
- lib/roby.rb,
lib/roby/app.rb,
lib/roby/plan.rb,
lib/roby/event.rb,
lib/roby/query.rb,
lib/roby/config.rb,
lib/roby/control.rb,
lib/roby/control.rb,
lib/roby/log/dot.rb,
lib/roby/support.rb,
lib/roby/app/rake.rb,
lib/roby/planning.rb,
lib/roby/interface.rb,
lib/roby/relations.rb,
lib/roby/exceptions.rb,
lib/roby/log/server.rb,
lib/roby/test/tools.rb,
lib/roby/log/timings.rb,
lib/roby/plan-object.rb,
lib/roby/propagation.rb,
lib/roby/state/state.rb,
lib/roby/test/common.rb,
lib/roby/thread_task.rb,
lib/roby/basic_object.rb,
lib/roby/state/events.rb,
lib/roby/transactions.rb,
lib/roby/log/chronicle.rb,
lib/roby/log/relations.rb,
lib/roby/planning/task.rb,
lib/roby/test/testcase.rb,
lib/roby/planning/loops.rb,
lib/roby/planning/model.rb,
lib/roby/standard_errors.rb,
lib/roby/task-operations.rb,
lib/roby/test/tasks/goto.rb,
lib/roby/decision_control.rb,
lib/roby/distributed/base.rb,
lib/roby/distributed/peer.rb,
lib/roby/log/event_stream.rb,
lib/roby/test/distributed.rb,
lib/roby/distributed/proxy.rb,
lib/roby/executives/simple.rb,
lib/roby/log/notifications.rb,
lib/roby/state/information.rb,
lib/roby/relations/conflicts.rb,
lib/roby/relations/influence.rb,
lib/roby/distributed/protocol.rb,
lib/roby/distributed/protocol.rb,
lib/roby/transactions/updates.rb,
lib/roby/test/tasks/empty_task.rb,
lib/roby/test/tasks/simple_task.rb,
lib/roby/distributed/transaction.rb,
lib/roby/distributed/subscription.rb,
lib/roby/distributed/communication.rb,
lib/roby/distributed/notifications.rb,
lib/roby/distributed/connection_space.rb,
lib/roby/distributed/distributed_object.rb,
ext/droby/dump.cc,
lib/roby/relations/planned_by.rb,
lib/roby/relations/hierarchy.rb
Overview
The main namespace for the Roby library. The namespace is divided as follows:
- Roby
-
core namespace for the Roby kernel
- Roby::Distributed
-
parts that are very specific to distributed plan management
- Roby::Planning
-
basic tools for plan generation
- Roby::Transactions
-
implementation of transactions
- Roby::EventStructure
-
event relations
- Roby::TaskStructure
-
task relations
Defined Under Namespace
Modules: ConflictEventHandling, DirectedRelationSupport, Distributed, EventGeneratorDisplay, EventStructure, ExceptionHandlingObject, Executives, Log, LoggedPlan, LoggedPlanObject, LoggedTask, Planning, Pos, Propagation, Rake, TaskOperations, TaskStructure, Test, Transactions Classes: Aborting, AndGenerator, AndTaskMatcher, Application, BasicObject, ChildFailedError, CodeError, CommandFailed, ConfigError, Control, ControlQuitError, CycleFoundError, DecisionControl, DeltaEvent, EmissionFailed, Event, EventCanceled, EventGenerator, EventHandlerError, EventNotControlable, EventNotExecutable, EventPreconditionFailed, ExecutionException, ExtendedStruct, FailedExceptionHandler, FilterGenerator, Group, Interface, InternalError, InvalidReplace, InvalidTransaction, LocalizedError, MissionFailedError, ModelViolation, NegateTaskMatcher, OrGenerator, OrTaskMatcher, OwnershipError, Parallel, Plan, PlanObject, PlanningFailedError, PlanningLoop, PlanningTask, Pool, PosDeltaEvent, PropagationError, Query, RelationGraph, RelationSpace, RemoteInterface, RemoteObjectProxy, RemotePeerMismatch, Sequence, SolverIgnoreUpdate, SolverInvalidateTransaction, SolverUpdateRelations, StateEvent, StateSpace, Task, TaskAggregator, TaskEventGenerator, TaskIndex, TaskMatcher, TaskModelTag, TaskNotExecutable, ThreadMismatch, ThreadTask, TimeDeltaEvent, TimeDistribution, TimePointEvent, Transaction, UnreachableEvent, UntilGenerator, YawDeltaEvent
Constant Summary collapse
- VERSION =
'0.7.2'- ROBY_LIB_DIR =
File.( File.join(File.dirname(__FILE__), '..') )
- ROBY_ROOT_DIR =
File.( File.join(ROBY_LIB_DIR, '..') )
- RX_IN_FRAMEWORK =
/^((?:\s*\(druby:\/\/.+\)\s*)?#{Regexp.quote(ROBY_LIB_DIR)}\/)/
Class Attribute Summary collapse
-
.condition_variables ⇒ Object
readonly
A pool of condition variables (as a Queue).
-
.control ⇒ Object
readonly
Returns the only one Control object.
-
.decision_control ⇒ Object
readonly
Returns the value of attribute decision_control.
-
.exception_handlers ⇒ Object
readonly
Returns the value of attribute exception_handlers.
-
.mutexes ⇒ Object
readonly
A pool of mutexes (as a Queue).
-
.plan ⇒ Object
readonly
Returns the executed plan.
Class Method Summary collapse
-
.app ⇒ Object
Returns the only one Application object.
-
.check_failed_missions(plan) ⇒ Object
Get all missions that have failed.
-
.condition_variable(mutex = false) ⇒ Object
call-seq: condition_variable => cv condition_variable(true) => cv, mutex condition_variable { |cv| … } => value returned by the block condition_variable(true) { |cv, mutex| … } => value returned by the block.
-
.control_thread ⇒ Object
Returns the control thread or, if control is not in a separate thread, Thread.main.
- .each_cycle(&block) ⇒ Object
- .each_exception_handler(&iterator) ⇒ Object
- .every(duration, &block) ⇒ Object
-
.execute ⇒ Object
Execute the given block inside the control thread, and returns when it has finished.
- .filter_backtrace(original_backtrace) ⇒ Object
- .format_exception(exception) ⇒ Object
-
.inside_control? ⇒ Boolean
True if the current thread is the control thread.
-
.load_all_relations ⇒ Object
Requires all Roby relation files (all files in roby/relations/).
- .log_exception(e, logger, level) ⇒ Object
-
.on_exception(*matchers, &handler) ⇒ Object
define_method(:each_exception_handler, &Roby::Propagation.exception_handlers.method(:each)).
-
.once ⇒ Object
Execute the given block in the control thread, but don’t wait for its completion like Roby.execute does.
-
.outside_control? ⇒ Boolean
True if the current thread is not control thread, or if there is not control thread.
-
.poll_state_events ⇒ Object
Registered on Control to call the #poll method of state events.
- .pretty_print_backtrace(pp, backtrace) ⇒ Object
-
.RelationSpace(klass) ⇒ Object
Creates a new relation space which applies on
klass. -
.return_condition_variable(cv, mutex = nil) ⇒ Object
Returns a ConditionVariable and optionally a Mutex into the Roby.condition_variables and Roby.mutexes pools.
- .wait_one_cycle ⇒ Object
-
.wait_until(ev) ⇒ Object
Stops the current thread until the given even is emitted.
Methods included from ExceptionHandlingObject
handle_exception, pass_exception
Class Attribute Details
.condition_variables ⇒ Object (readonly)
A pool of condition variables (as a Queue)
76 77 78 |
# File 'lib/roby/control.rb', line 76 def condition_variables @condition_variables end |
.control ⇒ Object (readonly)
Returns the only one Control object
24 25 26 |
# File 'lib/roby/control.rb', line 24 def control @control end |
.decision_control ⇒ Object (readonly)
Returns the value of attribute decision_control.
12 13 14 |
# File 'lib/roby/decision_control.rb', line 12 def decision_control @decision_control end |
.exception_handlers ⇒ Object (readonly)
Returns the value of attribute exception_handlers.
551 552 553 |
# File 'lib/roby/propagation.rb', line 551 def exception_handlers @exception_handlers end |
.mutexes ⇒ Object (readonly)
A pool of mutexes (as a Queue)
74 75 76 |
# File 'lib/roby/control.rb', line 74 def mutexes @mutexes end |
Class Method Details
.app ⇒ Object
Returns the only one Application object
12 |
# File 'lib/roby/app.rb', line 12 def self.app; Application.instance end |
.check_failed_missions(plan) ⇒ Object
Get all missions that have failed
732 733 734 735 736 737 738 |
# File 'lib/roby/control.rb', line 732 def self.check_failed_missions(plan) result = [] for task in plan.missions result << MissionFailedError.new(task) if task.failed? end result end |
.condition_variable(mutex = false) ⇒ Object
call-seq:
condition_variable => cv
condition_variable(true) => cv, mutex
condition_variable { |cv| ... } => value returned by the block
condition_variable(true) { |cv, mutex| ... } => value returned by the block
Get a condition variable object from the Roby.condition_variables pool and, if mutex is not true, a Mutex object
If a block is given, the two objects are yield and returned into the pool after the block has returned. In that case, the method returns the value returned by the block
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/roby/control.rb', line 90 def condition_variable(mutex = false) cv = condition_variables.pop if block_given? begin if mutex mt = mutexes.pop yield(cv, mt) else yield(cv) end ensure return_condition_variable(cv, mt) end else if mutex return cv, mutexes.pop else return cv end end end |
.control_thread ⇒ Object
Returns the control thread or, if control is not in a separate thread, Thread.main
38 39 40 |
# File 'lib/roby/control.rb', line 38 def control_thread Control.instance.thread || Thread.main end |
.each_cycle(&block) ⇒ Object
32 33 34 |
# File 'lib/roby/control.rb', line 32 def each_cycle(&block) Control.each_cycle(&block) end |
.each_exception_handler(&iterator) ⇒ Object
552 |
# File 'lib/roby/propagation.rb', line 552 def each_exception_handler(&iterator); exception_handlers.each(&iterator) end |
.every(duration, &block) ⇒ Object
29 30 31 |
# File 'lib/roby/control.rb', line 29 def every(duration, &block) Control.every(duration, &block) end |
.execute ⇒ Object
Execute the given block inside the control thread, and returns when it has finished. The return value is the value returned by the block
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'lib/roby/control.rb', line 116 def execute if Roby.inside_control? return Roby::Control.synchronize { yield } end cv = condition_variable return_value = nil Roby::Control.synchronize do if !Roby.control.running? raise "control thread not running" end caller_thread = Thread.current Control.waiting_threads << caller_thread Roby::Control.once do begin return_value = yield cv.broadcast rescue Exception => e caller_thread.raise e, e., e.backtrace end Control.waiting_threads.delete(caller_thread) end cv.wait(Roby::Control.mutex) end return_value ensure return_condition_variable(cv) end |
.filter_backtrace(original_backtrace) ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 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/exceptions.rb', line 147 def self.filter_backtrace(original_backtrace) if Roby.app.filter_backtraces? && original_backtrace app_dir = if defined? APP_DIR then Regexp.quote(APP_DIR) end original_backtrace = original_backtrace.dup backtrace_bottom = [] while !original_backtrace.empty? && original_backtrace.last !~ RX_IN_FRAMEWORK backtrace_bottom.unshift original_backtrace.pop end backtrace = original_backtrace.enum_for(:each_with_index).map do |line, idx| case line when /in `poll_handler'$/ line.gsub /:in.*/, ':in the polling handler' when /in `event_command_(\w+)'$/ line.gsub /:in.*/, ":in command for '#{$1}'" when /in `event_handler_(\w+)_(?:[a-f0-9]+)'$/ line.gsub /:in.*/, ":in event handler for '#{$1}'" else if original_backtrace.size > idx + 4 && original_backtrace[idx + 1] =~ /in `call'$/ && original_backtrace[idx + 2] =~ /in `call_handlers'$/ && original_backtrace[idx + 3] =~ /`each'$/ && original_backtrace[idx + 4] =~ /`each_handler'$/ line.gsub /:in /, ":in event handler, " else case line when /in `(gem_original_)?require'$/ when /^((?:\s*\(druby:\/\/.+\)\s*)?#{Regexp.quote(ROBY_LIB_DIR)}\/)/ when /^(#{app_dir}\/)?scripts\// when /^\(eval\):\d+:in `each(?:_handler)?'/ else line end end end end while !backtrace.empty? && !backtrace.last backtrace.pop end backtrace.each_with_index do |line, i| backtrace[i] = line || original_backtrace[i] end if app_dir backtrace = backtrace.map do |line| line.gsub /^#{app_dir}\/?/, './' end end backtrace.concat backtrace_bottom end backtrace || original_backtrace || [] end |
.format_exception(exception) ⇒ Object
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 |
# File 'lib/roby/exceptions.rb', line 211 def self.format_exception(exception) = begin PP.pp(exception, "") rescue Exception => formatting_error begin "error formatting exception\n" + exception. + "\nplease report the formatting error: \n" + formatting_error. rescue Exception => formatting_error "\nerror formatting exception\n" + formatting_error. end end .split("\n") end |
.inside_control? ⇒ Boolean
True if the current thread is the control thread
See #outside_control? for a discussion of the use of #inside_control? and #outside_control? when testing the threading context
46 47 48 49 |
# File 'lib/roby/control.rb', line 46 def inside_control? t = Control.instance.thread !t || t == Thread.current end |
.load_all_relations ⇒ Object
Requires all Roby relation files (all files in roby/relations/)
577 578 579 580 581 |
# File 'lib/roby/relations.rb', line 577 def self.load_all_relations Dir.glob("#{File.dirname(__FILE__)}/relations/*.rb").each do |file| require "roby/relations/#{File.basename(file, '.rb')}" end end |
.log_exception(e, logger, level) ⇒ Object
228 229 230 231 232 |
# File 'lib/roby/exceptions.rb', line 228 def self.log_exception(e, logger, level) format_exception(e).each do |line| logger.send(level, line) end end |
.on_exception(*matchers, &handler) ⇒ Object
define_method(:each_exception_handler, &Roby::Propagation.exception_handlers.method(:each))
554 555 556 557 |
# File 'lib/roby/propagation.rb', line 554 def on_exception(*matchers, &handler) check_arity(handler, 2) exception_handlers.unshift [matchers, handler] end |
.once ⇒ Object
Execute the given block in the control thread, but don’t wait for its completion like Roby.execute does
151 152 153 |
# File 'lib/roby/control.rb', line 151 def once Roby::Control.once { yield } end |
.outside_control? ⇒ Boolean
True if the current thread is not control thread, or if there is not control thread. When you check the current thread context, always use a negated form. Do not do
if Roby.inside_control?
ERROR
end
Do instead
if !Roby.outside_control?
ERROR
end
Since the first form will fail if there is no control thread, while the second form will work. Use the first form only if you require that there actually IS a control thread.
68 69 70 71 |
# File 'lib/roby/control.rb', line 68 def outside_control? t = Control.instance.thread !t || t != Thread.current end |
.poll_state_events ⇒ Object
Registered on Control to call the #poll method of state events
65 66 67 68 69 70 71 |
# File 'lib/roby/state/events.rb', line 65 def self.poll_state_events # :nodoc: for ev in Roby.plan.free_events if ev.kind_of?(StateEvent) && ev.enabled? ev.poll end end end |
.pretty_print_backtrace(pp, backtrace) ⇒ Object
203 204 205 206 207 208 209 |
# File 'lib/roby/exceptions.rb', line 203 def self.pretty_print_backtrace(pp, backtrace) if backtrace && !backtrace.empty? pp.group(2) do pp.seplist(filter_backtrace(backtrace)) { |line| pp.text line } end end end |
.RelationSpace(klass) ⇒ Object
Creates a new relation space which applies on klass. If a block is given, it is eval’d in the context of the new relation space instance
569 570 571 572 573 574 |
# File 'lib/roby/relations.rb', line 569 def self.RelationSpace(klass) klass.include DirectedRelationSupport relation_space = RelationSpace.new relation_space.apply_on klass relation_space end |
.return_condition_variable(cv, mutex = nil) ⇒ Object
Returns a ConditionVariable and optionally a Mutex into the Roby.condition_variables and Roby.mutexes pools
184 185 186 187 188 189 190 |
# File 'lib/roby/control.rb', line 184 def return_condition_variable(cv, mutex = nil) condition_variables.push cv if mutex mutexes.push mutex end nil end |
.wait_one_cycle ⇒ Object
154 155 156 |
# File 'lib/roby/control.rb', line 154 def wait_one_cycle Roby.control.wait_one_cycle end |
.wait_until(ev) ⇒ Object
Stops the current thread until the given even is emitted
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/roby/control.rb', line 159 def wait_until(ev) if Roby.inside_control? raise ThreadMismatch, "cannot use #wait_until in control thread" end condition_variable(true) do |cv, mt| caller_thread = Thread.current mt.synchronize do Roby::Control.once do ev.if_unreachable(true) do |reason| caller_thread.raise UnreachableEvent.new(ev, reason) end ev.on do mt.synchronize { cv.broadcast } end yield end cv.wait(mt) end end end |