roby 0.8.0 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (644) hide show
  1. checksums.yaml +7 -0
  2. data/.deep-cover.rb +3 -0
  3. data/.gitattributes +1 -0
  4. data/.gitignore +24 -0
  5. data/.simplecov +10 -0
  6. data/.travis.yml +17 -0
  7. data/.yardopts +4 -0
  8. data/Gemfile +15 -0
  9. data/README.md +11 -0
  10. data/Rakefile +47 -177
  11. data/benchmark/{alloc_misc.rb → attic/alloc_misc.rb} +2 -2
  12. data/benchmark/{discovery_latency.rb → attic/discovery_latency.rb} +19 -19
  13. data/benchmark/{garbage_collection.rb → attic/garbage_collection.rb} +9 -9
  14. data/benchmark/{genom.rb → attic/genom.rb} +0 -0
  15. data/benchmark/attic/transactions.rb +62 -0
  16. data/benchmark/plan_basic_operations.rb +28 -0
  17. data/benchmark/relations/graph.rb +63 -0
  18. data/benchmark/ruby/identity.rb +18 -0
  19. data/benchmark/ruby/set_intersect_vs_hash_merge.rb +39 -0
  20. data/benchmark/ruby/yield_vs_block.rb +35 -0
  21. data/benchmark/run +5 -0
  22. data/benchmark/synthetic_plan_modifications_with_transactions.rb +79 -0
  23. data/benchmark/transactions.rb +99 -51
  24. data/bin/roby +38 -197
  25. data/bin/roby-display +14 -0
  26. data/bin/roby-log +3 -176
  27. data/doc/guide/{src → attic}/abstraction/achieve_with.page +1 -1
  28. data/doc/guide/{src → attic}/abstraction/forwarding.page +1 -1
  29. data/doc/guide/{src → attic}/abstraction/hierarchy.page +1 -1
  30. data/doc/guide/{src → attic}/abstraction/index.page +1 -1
  31. data/doc/guide/{src → attic}/abstraction/task_models.page +1 -1
  32. data/doc/guide/{overview.rdoc → attic/cycle/api_overview.rdoc} +6 -1
  33. data/doc/guide/{src → attic}/cycle/cycle-overview.png +0 -0
  34. data/doc/guide/{src → attic}/cycle/cycle-overview.svg +0 -0
  35. data/doc/guide/attic/cycle/error_handling.page +98 -0
  36. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.png +0 -0
  37. data/doc/guide/{src → attic}/cycle/error_instantaneous_repair.svg +0 -0
  38. data/doc/guide/{src/cycle/error_handling.page → attic/cycle/error_sources.page} +46 -89
  39. data/doc/guide/{src → attic}/cycle/garbage_collection.page +1 -1
  40. data/doc/guide/{src → attic}/cycle/index.page +1 -1
  41. data/doc/guide/{src → attic}/cycle/propagation.page +11 -1
  42. data/doc/guide/{src → attic}/cycle/propagation_diamond.png +0 -0
  43. data/doc/guide/{src → attic}/cycle/propagation_diamond.svg +0 -0
  44. data/doc/guide/attic/plans/building_plans.page +89 -0
  45. data/doc/guide/attic/plans/code.page +192 -0
  46. data/doc/guide/{src/basics → attic/plans}/events.page +3 -4
  47. data/doc/guide/attic/plans/index.page +7 -0
  48. data/doc/guide/{plan_modifications.rdoc → attic/plans/plan_modifications.rdoc} +5 -3
  49. data/doc/guide/{src/basics → attic/plans}/plan_objects.page +2 -1
  50. data/doc/guide/attic/plans/querying_plans.page +5 -0
  51. data/doc/guide/{src/basics → attic/plans}/tasks.page +20 -20
  52. data/doc/guide/config.yaml +7 -4
  53. data/doc/guide/ext/extended_menu.rb +29 -0
  54. data/doc/guide/ext/init.rb +6 -0
  55. data/doc/guide/ext/rdoc_links.rb +7 -6
  56. data/doc/guide/src/advanced_concepts/history.page +5 -0
  57. data/doc/guide/src/advanced_concepts/index.page +11 -0
  58. data/doc/guide/src/advanced_concepts/recognizing_patterns.page +83 -0
  59. data/doc/guide/src/advanced_concepts/scheduling.page +87 -0
  60. data/doc/guide/src/advanced_concepts/transactions.page +5 -0
  61. data/doc/guide/src/advanced_concepts/unreachability.page +42 -0
  62. data/doc/guide/src/base.template +96 -0
  63. data/doc/guide/src/basics_shell_header.txt +5 -7
  64. data/doc/guide/src/building/action_coordination.page +96 -0
  65. data/doc/guide/src/building/actions.page +124 -0
  66. data/doc/guide/src/building/file_layout.page +71 -0
  67. data/doc/guide/src/building/index.page +50 -0
  68. data/doc/guide/src/building/patterns.page +86 -0
  69. data/doc/guide/src/building/patterns_forwarding.png +0 -0
  70. data/doc/guide/src/building/patterns_forwarding.svg +277 -0
  71. data/doc/guide/src/building/runtime.page +95 -0
  72. data/doc/guide/src/building/task_models.page +94 -0
  73. data/doc/guide/src/building/tasks.page +284 -0
  74. data/doc/guide/src/concepts/error_handling.page +100 -0
  75. data/doc/guide/src/concepts/exception_propagation.png +0 -0
  76. data/doc/guide/src/concepts/exception_propagation.svg +445 -0
  77. data/doc/guide/src/concepts/execution.page +85 -0
  78. data/doc/guide/src/concepts/execution.png +0 -0
  79. data/doc/guide/src/concepts/execution.svg +573 -0
  80. data/doc/guide/src/concepts/execution_cycle.png +0 -0
  81. data/doc/guide/src/concepts/garbage_collection.page +57 -0
  82. data/doc/guide/src/concepts/index.page +27 -0
  83. data/doc/guide/src/concepts/plans.page +101 -0
  84. data/doc/guide/src/concepts/policy.page +31 -0
  85. data/doc/guide/src/concepts/reactor.page +61 -0
  86. data/doc/guide/src/concepts/simple_plan_example.png +0 -0
  87. data/doc/guide/src/concepts/simple_plan_example.svg +376 -0
  88. data/doc/guide/src/default.template +9 -74
  89. data/doc/guide/src/event_relations/forward.page +71 -0
  90. data/doc/guide/src/event_relations/index.page +12 -0
  91. data/doc/guide/src/event_relations/scheduling_constraints.page +43 -0
  92. data/doc/guide/src/event_relations/signal.page +55 -0
  93. data/doc/guide/src/event_relations/temporal_constraints.page +77 -0
  94. data/doc/guide/src/htmldoc.metainfo +21 -8
  95. data/doc/guide/src/index.page +8 -3
  96. data/doc/guide/src/{introduction/install.page → installation/index.page} +37 -25
  97. data/doc/guide/src/installation/publications.page +14 -0
  98. data/doc/guide/src/{introduction → installation}/videos.page +14 -7
  99. data/doc/guide/src/interacting/index.page +16 -0
  100. data/doc/guide/src/interacting/run.page +33 -0
  101. data/doc/guide/src/interacting/shell.page +95 -0
  102. data/doc/guide/src/plugins/creating_plugins.page +72 -0
  103. data/doc/guide/src/plugins/index.page +27 -5
  104. data/doc/guide/src/plugins/{fault_tolerance.page → standard_plugins/fault_tolerance.page} +2 -2
  105. data/doc/guide/src/plugins/standard_plugins/index.page +11 -0
  106. data/doc/guide/src/plugins/{subsystems.page → standard_plugins/subsystems.page} +2 -2
  107. data/doc/guide/src/style_screen.css +687 -0
  108. data/doc/guide/src/task_relations/dependency.page +107 -0
  109. data/doc/guide/src/task_relations/executed_by.page +77 -0
  110. data/doc/guide/src/task_relations/index.page +12 -0
  111. data/doc/guide/src/task_relations/new_relations.page +119 -0
  112. data/doc/guide/src/task_relations/planned_by.page +46 -0
  113. data/doc/guide/src/tutorial/app.page +117 -0
  114. data/doc/guide/src/{basics → tutorial}/code_examples.page +6 -5
  115. data/doc/guide/src/{basics → tutorial}/dry.page +15 -15
  116. data/doc/guide/src/{basics → tutorial}/errors.page +43 -68
  117. data/doc/guide/src/tutorial/events.page +195 -0
  118. data/doc/guide/src/{basics → tutorial}/hierarchy.page +53 -52
  119. data/doc/guide/src/tutorial/index.page +13 -0
  120. data/doc/guide/src/tutorial/log_replay/goForward_1.png +0 -0
  121. data/doc/guide/src/tutorial/log_replay/goForward_2.png +0 -0
  122. data/doc/guide/src/tutorial/log_replay/goForward_3.png +0 -0
  123. data/doc/guide/src/{basics → tutorial}/log_replay/goForward_4.png +0 -0
  124. data/doc/guide/src/tutorial/log_replay/goForward_5.png +0 -0
  125. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_1.png +0 -0
  126. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_2.png +0 -0
  127. data/doc/guide/src/{basics → tutorial}/log_replay/hierarchy_error_3.png +0 -0
  128. data/doc/guide/src/tutorial/log_replay/moveto_code_error.png +0 -0
  129. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_1.png +0 -0
  130. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_2.png +0 -0
  131. data/doc/guide/src/{basics → tutorial}/log_replay/plan_repair_3.png +0 -0
  132. data/doc/guide/src/tutorial/log_replay/plan_repair_4.png +0 -0
  133. data/doc/guide/src/tutorial/log_replay/roby_log_main_window.png +0 -0
  134. data/doc/guide/src/{basics → tutorial}/log_replay/roby_log_relation_window.png +0 -0
  135. data/doc/guide/src/{basics → tutorial}/log_replay/roby_replay_event_representation.png +0 -0
  136. data/doc/guide/src/tutorial/relations_display.page +153 -0
  137. data/doc/guide/src/{basics → tutorial}/roby_cycle_overview.png +0 -0
  138. data/doc/guide/src/tutorial/shell.page +121 -0
  139. data/doc/guide/src/{basics → tutorial}/summary.page +1 -1
  140. data/doc/guide/src/tutorial/tasks.page +374 -0
  141. data/lib/roby.rb +102 -47
  142. data/lib/roby/actions.rb +17 -0
  143. data/lib/roby/actions/action.rb +80 -0
  144. data/lib/roby/actions/interface.rb +45 -0
  145. data/lib/roby/actions/library.rb +23 -0
  146. data/lib/roby/actions/models/action.rb +224 -0
  147. data/lib/roby/actions/models/coordination_action.rb +58 -0
  148. data/lib/roby/actions/models/interface.rb +22 -0
  149. data/lib/roby/actions/models/interface_base.rb +294 -0
  150. data/lib/roby/actions/models/library.rb +12 -0
  151. data/lib/roby/actions/models/method_action.rb +90 -0
  152. data/lib/roby/actions/task.rb +114 -0
  153. data/lib/roby/and_generator.rb +125 -0
  154. data/lib/roby/app.rb +2795 -829
  155. data/lib/roby/app/autotest_console_reporter.rb +138 -0
  156. data/lib/roby/app/base.rb +21 -0
  157. data/lib/roby/app/cucumber.rb +2 -0
  158. data/lib/roby/app/cucumber/controller.rb +439 -0
  159. data/lib/roby/app/cucumber/helpers.rb +280 -0
  160. data/lib/roby/app/cucumber/world.rb +32 -0
  161. data/lib/roby/app/debug.rb +136 -0
  162. data/lib/roby/app/gen.rb +2 -0
  163. data/lib/roby/app/rake.rb +178 -38
  164. data/lib/roby/app/robot_config.rb +9 -0
  165. data/lib/roby/app/robot_names.rb +115 -0
  166. data/lib/roby/app/run.rb +3 -2
  167. data/lib/roby/app/scripts.rb +72 -0
  168. data/lib/roby/app/scripts/autotest.rb +173 -0
  169. data/lib/roby/app/scripts/display.rb +2 -0
  170. data/lib/roby/app/scripts/restart.rb +52 -0
  171. data/lib/roby/app/scripts/results.rb +17 -8
  172. data/lib/roby/app/scripts/run.rb +155 -24
  173. data/lib/roby/app/scripts/shell.rb +147 -62
  174. data/lib/roby/app/scripts/test.rb +107 -22
  175. data/lib/roby/app/test_reporter.rb +74 -0
  176. data/lib/roby/app/test_server.rb +159 -0
  177. data/lib/roby/app/vagrant.rb +47 -0
  178. data/lib/roby/backports.rb +16 -0
  179. data/lib/roby/cli/display.rb +190 -0
  180. data/lib/roby/cli/exceptions.rb +17 -0
  181. data/lib/roby/cli/gen/actions/class.rb +5 -0
  182. data/lib/roby/cli/gen/actions/test.rb +6 -0
  183. data/lib/roby/cli/gen/app/.yardopts +6 -0
  184. data/lib/roby/cli/gen/app/README.md +28 -0
  185. data/lib/roby/cli/gen/app/Rakefile +15 -0
  186. data/{app → lib/roby/cli/gen/app}/config/app.yml +29 -39
  187. data/lib/roby/cli/gen/app/models/.gitattributes +1 -0
  188. data/{app → lib/roby/cli/gen/app/scripts}/controllers/.gitattributes +0 -0
  189. data/{app/data/.gitattributes → lib/roby/cli/gen/app/test/.gitignore} +0 -0
  190. data/lib/roby/cli/gen/class/class.rb +6 -0
  191. data/lib/roby/cli/gen/class/test.rb +7 -0
  192. data/lib/roby/cli/gen/helpers.rb +203 -0
  193. data/lib/roby/cli/gen/module/module.rb +5 -0
  194. data/lib/roby/cli/gen/module/test.rb +6 -0
  195. data/lib/roby/cli/gen/roby_app/config/init.rb +17 -0
  196. data/lib/roby/cli/gen/roby_app/config/robots/robot.rb +40 -0
  197. data/lib/roby/cli/gen/task/class.rb +44 -0
  198. data/lib/roby/cli/gen/task/test.rb +6 -0
  199. data/lib/roby/cli/gen_main.rb +120 -0
  200. data/lib/roby/cli/log.rb +276 -0
  201. data/lib/roby/cli/log/flamegraph.html +499 -0
  202. data/lib/roby/cli/log/flamegraph_renderer.rb +88 -0
  203. data/lib/roby/cli/main.rb +153 -0
  204. data/lib/roby/coordination.rb +60 -0
  205. data/lib/roby/coordination/action_script.rb +25 -0
  206. data/lib/roby/coordination/action_state_machine.rb +125 -0
  207. data/lib/roby/coordination/actions.rb +106 -0
  208. data/lib/roby/coordination/base.rb +145 -0
  209. data/lib/roby/coordination/calculus.rb +40 -0
  210. data/lib/roby/coordination/child.rb +28 -0
  211. data/lib/roby/coordination/event.rb +29 -0
  212. data/lib/roby/coordination/fault_handler.rb +25 -0
  213. data/lib/roby/coordination/fault_handling_task.rb +13 -0
  214. data/lib/roby/coordination/fault_response_table.rb +110 -0
  215. data/lib/roby/coordination/models/action_script.rb +64 -0
  216. data/lib/roby/coordination/models/action_state_machine.rb +224 -0
  217. data/lib/roby/coordination/models/actions.rb +191 -0
  218. data/lib/roby/coordination/models/arguments.rb +55 -0
  219. data/lib/roby/coordination/models/base.rb +176 -0
  220. data/lib/roby/coordination/models/capture.rb +86 -0
  221. data/lib/roby/coordination/models/child.rb +35 -0
  222. data/lib/roby/coordination/models/event.rb +41 -0
  223. data/lib/roby/coordination/models/exceptions.rb +42 -0
  224. data/lib/roby/coordination/models/fault_handler.rb +219 -0
  225. data/lib/roby/coordination/models/fault_response_table.rb +77 -0
  226. data/lib/roby/coordination/models/root.rb +22 -0
  227. data/lib/roby/coordination/models/script.rb +283 -0
  228. data/lib/roby/coordination/models/task.rb +184 -0
  229. data/lib/roby/coordination/models/task_from_action.rb +50 -0
  230. data/lib/roby/coordination/models/task_from_as_plan.rb +33 -0
  231. data/lib/roby/coordination/models/task_from_instanciation_object.rb +31 -0
  232. data/lib/roby/coordination/models/task_from_variable.rb +27 -0
  233. data/lib/roby/coordination/models/task_with_dependencies.rb +48 -0
  234. data/lib/roby/coordination/models/variable.rb +32 -0
  235. data/lib/roby/coordination/script.rb +200 -0
  236. data/lib/roby/coordination/script_instruction.rb +12 -0
  237. data/lib/roby/coordination/task.rb +45 -0
  238. data/lib/roby/coordination/task_base.rb +69 -0
  239. data/lib/roby/coordination/task_script.rb +293 -0
  240. data/lib/roby/coordination/task_state_machine.rb +308 -0
  241. data/lib/roby/decision_control.rb +33 -21
  242. data/lib/roby/distributed_object.rb +76 -0
  243. data/lib/roby/droby.rb +17 -0
  244. data/lib/roby/droby/droby_id.rb +6 -0
  245. data/lib/roby/droby/enable.rb +153 -0
  246. data/lib/roby/droby/event_logger.rb +189 -0
  247. data/lib/roby/droby/event_logging.rb +57 -0
  248. data/lib/roby/droby/exceptions.rb +14 -0
  249. data/lib/roby/droby/identifiable.rb +22 -0
  250. data/lib/roby/droby/logfile.rb +141 -0
  251. data/lib/roby/droby/logfile/client.rb +176 -0
  252. data/lib/roby/droby/logfile/file_format.md +97 -0
  253. data/lib/roby/droby/logfile/index.rb +117 -0
  254. data/lib/roby/droby/logfile/reader.rb +139 -0
  255. data/lib/roby/droby/logfile/server.rb +199 -0
  256. data/lib/roby/droby/logfile/writer.rb +114 -0
  257. data/lib/roby/droby/marshal.rb +264 -0
  258. data/lib/roby/droby/marshallable.rb +12 -0
  259. data/lib/roby/droby/null_event_logger.rb +25 -0
  260. data/lib/roby/droby/object_manager.rb +205 -0
  261. data/lib/roby/droby/peer_id.rb +6 -0
  262. data/lib/roby/droby/plan_rebuilder.rb +373 -0
  263. data/lib/roby/droby/rebuilt_plan.rb +160 -0
  264. data/lib/roby/droby/remote_droby_id.rb +6 -0
  265. data/lib/roby/droby/timepoints.rb +205 -0
  266. data/lib/roby/droby/timepoints_ctf.metadata.erb +101 -0
  267. data/lib/roby/droby/timepoints_ctf.rb +125 -0
  268. data/lib/roby/droby/v5.rb +14 -0
  269. data/lib/roby/droby/v5/builtin.rb +120 -0
  270. data/lib/roby/droby/v5/droby_class.rb +45 -0
  271. data/lib/roby/droby/v5/droby_constant.rb +81 -0
  272. data/lib/roby/droby/v5/droby_dump.rb +1026 -0
  273. data/lib/roby/droby/v5/droby_id.rb +44 -0
  274. data/lib/roby/droby/v5/droby_model.rb +82 -0
  275. data/lib/roby/droby/v5/peer_id.rb +10 -0
  276. data/lib/roby/droby/v5/remote_droby_id.rb +42 -0
  277. data/lib/roby/event.rb +79 -957
  278. data/lib/roby/event_constraints.rb +835 -0
  279. data/lib/roby/event_generator.rb +1047 -0
  280. data/lib/roby/event_structure/causal_link.rb +6 -0
  281. data/lib/roby/event_structure/forwarding.rb +6 -0
  282. data/lib/roby/event_structure/precedence.rb +7 -0
  283. data/lib/roby/event_structure/signal.rb +8 -0
  284. data/lib/roby/event_structure/temporal_constraints.rb +640 -0
  285. data/lib/roby/exceptions.rb +446 -152
  286. data/lib/roby/executable_plan.rb +549 -0
  287. data/lib/roby/execution_engine.rb +1997 -950
  288. data/lib/roby/filter_generator.rb +26 -0
  289. data/lib/roby/gui/chronicle_view.rb +225 -0
  290. data/lib/roby/gui/chronicle_widget.rb +925 -0
  291. data/lib/roby/gui/dot_id.rb +11 -0
  292. data/lib/roby/gui/exception_view.rb +44 -0
  293. data/lib/roby/gui/log_display.rb +273 -0
  294. data/lib/roby/gui/model_views.rb +2 -0
  295. data/lib/roby/gui/model_views/action_interface.rb +53 -0
  296. data/lib/roby/gui/model_views/task.rb +47 -0
  297. data/lib/roby/gui/model_views/task.rhtml +41 -0
  298. data/lib/roby/gui/object_info_view.rb +89 -0
  299. data/lib/roby/gui/plan_dot_layout.rb +427 -0
  300. data/lib/roby/gui/plan_rebuilder_widget.rb +357 -0
  301. data/lib/roby/gui/qt4_toMSecsSinceEpoch.rb +8 -0
  302. data/lib/roby/gui/relations_view.rb +278 -0
  303. data/lib/roby/gui/relations_view/relations.ui +139 -0
  304. data/lib/roby/gui/relations_view/relations_canvas.rb +1088 -0
  305. data/lib/roby/gui/relations_view/relations_config.rb +292 -0
  306. data/lib/roby/gui/relations_view/relations_view.ui +53 -0
  307. data/lib/roby/gui/scheduler_view.css +24 -0
  308. data/lib/roby/gui/scheduler_view.rb +46 -0
  309. data/lib/roby/gui/scheduler_view.rhtml +53 -0
  310. data/lib/roby/gui/stepping.rb +93 -0
  311. data/lib/roby/gui/stepping.ui +181 -0
  312. data/lib/roby/gui/styles.rb +81 -0
  313. data/lib/roby/gui/task_display_configuration.rb +42 -0
  314. data/lib/roby/gui/task_state_at.rb +38 -0
  315. data/lib/roby/hooks.rb +26 -0
  316. data/lib/roby/interface.rb +136 -469
  317. data/lib/roby/interface/async.rb +20 -0
  318. data/lib/roby/interface/async/action_monitor.rb +188 -0
  319. data/lib/roby/interface/async/interface.rb +498 -0
  320. data/lib/roby/interface/async/job_monitor.rb +213 -0
  321. data/lib/roby/interface/async/log.rb +238 -0
  322. data/lib/roby/interface/async/new_job_listener.rb +79 -0
  323. data/lib/roby/interface/async/ui_connector.rb +183 -0
  324. data/lib/roby/interface/client.rb +553 -0
  325. data/lib/roby/interface/command.rb +24 -0
  326. data/lib/roby/interface/command_argument.rb +16 -0
  327. data/lib/roby/interface/command_library.rb +92 -0
  328. data/lib/roby/interface/droby_channel.rb +174 -0
  329. data/lib/roby/interface/exceptions.rb +22 -0
  330. data/lib/roby/interface/interface.rb +655 -0
  331. data/lib/roby/interface/job.rb +47 -0
  332. data/lib/roby/interface/rest.rb +10 -0
  333. data/lib/roby/interface/rest/api.rb +29 -0
  334. data/lib/roby/interface/rest/helpers.rb +24 -0
  335. data/lib/roby/interface/rest/server.rb +212 -0
  336. data/lib/roby/interface/server.rb +154 -0
  337. data/lib/roby/interface/shell_client.rb +468 -0
  338. data/lib/roby/interface/shell_subcommand.rb +24 -0
  339. data/lib/roby/interface/subcommand_client.rb +35 -0
  340. data/lib/roby/interface/tcp.rb +168 -0
  341. data/lib/roby/models/arguments.rb +112 -0
  342. data/lib/roby/models/plan_object.rb +83 -0
  343. data/lib/roby/models/task.rb +835 -0
  344. data/lib/roby/models/task_event.rb +62 -0
  345. data/lib/roby/models/task_service.rb +78 -0
  346. data/lib/roby/or_generator.rb +88 -0
  347. data/lib/roby/plan.rb +1751 -864
  348. data/lib/roby/plan_object.rb +611 -0
  349. data/lib/roby/plan_service.rb +200 -0
  350. data/lib/roby/promise.rb +332 -0
  351. data/lib/roby/queries.rb +23 -0
  352. data/lib/roby/queries/and_matcher.rb +32 -0
  353. data/lib/roby/queries/any.rb +27 -0
  354. data/lib/roby/queries/code_error_matcher.rb +58 -0
  355. data/lib/roby/queries/event_generator_matcher.rb +9 -0
  356. data/lib/roby/queries/execution_exception_matcher.rb +165 -0
  357. data/lib/roby/queries/index.rb +165 -0
  358. data/lib/roby/queries/localized_error_matcher.rb +149 -0
  359. data/lib/roby/queries/matcher_base.rb +107 -0
  360. data/lib/roby/queries/none.rb +27 -0
  361. data/lib/roby/queries/not_matcher.rb +30 -0
  362. data/lib/roby/queries/op_matcher.rb +8 -0
  363. data/lib/roby/queries/or_matcher.rb +30 -0
  364. data/lib/roby/queries/plan_object_matcher.rb +363 -0
  365. data/lib/roby/queries/query.rb +188 -0
  366. data/lib/roby/queries/task_event_generator_matcher.rb +86 -0
  367. data/lib/roby/queries/task_matcher.rb +344 -0
  368. data/lib/roby/relations.rb +42 -678
  369. data/lib/roby/relations/bidirectional_directed_adjacency_graph.rb +492 -0
  370. data/lib/roby/relations/directed_relation_support.rb +268 -0
  371. data/lib/roby/relations/event_relation_graph.rb +19 -0
  372. data/lib/roby/relations/fork_merge_visitor.rb +154 -0
  373. data/lib/roby/relations/graph.rb +533 -0
  374. data/lib/roby/relations/models/directed_relation_support.rb +11 -0
  375. data/lib/roby/relations/models/graph.rb +75 -0
  376. data/lib/roby/relations/models/task_relation_graph.rb +18 -0
  377. data/lib/roby/relations/space.rb +380 -0
  378. data/lib/roby/relations/task_relation_graph.rb +20 -0
  379. data/lib/roby/robot.rb +85 -38
  380. data/lib/roby/schedulers/basic.rb +155 -25
  381. data/lib/roby/schedulers/null.rb +20 -0
  382. data/lib/roby/schedulers/reporting.rb +31 -0
  383. data/lib/roby/schedulers/state.rb +129 -0
  384. data/lib/roby/schedulers/temporal.rb +91 -0
  385. data/lib/roby/singletons.rb +87 -0
  386. data/lib/roby/standalone.rb +4 -2
  387. data/lib/roby/standard_errors.rb +405 -82
  388. data/lib/roby/state.rb +6 -3
  389. data/lib/roby/state/conf_model.rb +5 -0
  390. data/lib/roby/state/events.rb +181 -95
  391. data/lib/roby/state/goal_model.rb +77 -0
  392. data/lib/roby/state/open_struct.rb +591 -0
  393. data/lib/roby/state/open_struct_model.rb +68 -0
  394. data/lib/roby/state/pos.rb +45 -45
  395. data/lib/roby/state/shapes.rb +11 -11
  396. data/lib/roby/state/state_model.rb +303 -0
  397. data/lib/roby/state/task.rb +43 -0
  398. data/lib/roby/support.rb +88 -148
  399. data/lib/roby/task.rb +1361 -1750
  400. data/lib/roby/task_arguments.rb +428 -0
  401. data/lib/roby/task_event.rb +127 -0
  402. data/lib/roby/task_event_generator.rb +337 -0
  403. data/lib/roby/task_service.rb +6 -0
  404. data/lib/roby/task_structure/conflicts.rb +104 -0
  405. data/lib/roby/task_structure/dependency.rb +932 -0
  406. data/lib/roby/task_structure/error_handling.rb +118 -0
  407. data/lib/roby/task_structure/executed_by.rb +234 -0
  408. data/lib/roby/task_structure/planned_by.rb +90 -0
  409. data/lib/roby/tasks/aggregator.rb +37 -0
  410. data/lib/roby/tasks/external_process.rb +275 -0
  411. data/lib/roby/tasks/group.rb +27 -0
  412. data/lib/roby/tasks/null.rb +19 -0
  413. data/lib/roby/tasks/parallel.rb +43 -0
  414. data/lib/roby/tasks/sequence.rb +88 -0
  415. data/lib/roby/tasks/simple.rb +21 -0
  416. data/lib/roby/{thread_task.rb → tasks/thread.rb} +50 -24
  417. data/lib/roby/tasks/timeout.rb +17 -0
  418. data/lib/roby/tasks/virtual.rb +55 -0
  419. data/lib/roby/template_plan.rb +7 -0
  420. data/lib/roby/test/aruba_minitest.rb +74 -0
  421. data/lib/roby/test/assertion.rb +16 -0
  422. data/lib/roby/test/assertions.rb +490 -0
  423. data/lib/roby/test/common.rb +368 -591
  424. data/lib/roby/test/dsl.rb +149 -0
  425. data/lib/roby/test/error.rb +18 -0
  426. data/lib/roby/test/event_reporter.rb +83 -0
  427. data/lib/roby/test/execution_expectations.rb +1134 -0
  428. data/lib/roby/test/expect_execution.rb +151 -0
  429. data/lib/roby/test/minitest_helpers.rb +166 -0
  430. data/lib/roby/test/roby_app_helpers.rb +200 -0
  431. data/lib/roby/test/run_planners.rb +155 -0
  432. data/lib/roby/test/self.rb +112 -0
  433. data/lib/roby/test/spec.rb +198 -0
  434. data/lib/roby/test/tasks/empty_task.rb +4 -4
  435. data/lib/roby/test/tasks/goto.rb +28 -27
  436. data/lib/roby/test/teardown_plans.rb +100 -0
  437. data/lib/roby/test/testcase.rb +239 -307
  438. data/lib/roby/test/tools.rb +159 -155
  439. data/lib/roby/test/validate_state_machine.rb +75 -0
  440. data/lib/roby/transaction.rb +1125 -0
  441. data/lib/roby/transaction/event_generator_proxy.rb +63 -0
  442. data/lib/roby/transaction/plan_object_proxy.rb +99 -0
  443. data/lib/roby/transaction/plan_service_proxy.rb +43 -0
  444. data/lib/roby/transaction/proxying.rb +120 -0
  445. data/lib/roby/transaction/task_event_generator_proxy.rb +19 -0
  446. data/lib/roby/transaction/task_proxy.rb +135 -0
  447. data/lib/roby/until_generator.rb +30 -0
  448. data/lib/roby/version.rb +5 -0
  449. data/lib/roby/yard.rb +169 -0
  450. data/lib/yard-roby.rb +1 -0
  451. data/manifest.xml +32 -6
  452. data/roby.gemspec +59 -0
  453. metadata +788 -587
  454. data/Manifest.txt +0 -321
  455. data/NOTES +0 -4
  456. data/README.txt +0 -166
  457. data/TODO.txt +0 -146
  458. data/app/README.txt +0 -24
  459. data/app/Rakefile +0 -8
  460. data/app/config/ROBOT.rb +0 -5
  461. data/app/config/init.rb +0 -33
  462. data/app/config/roby.yml +0 -3
  463. data/app/controllers/ROBOT.rb +0 -2
  464. data/app/planners/ROBOT/main.rb +0 -6
  465. data/app/planners/main.rb +0 -5
  466. data/app/scripts/distributed +0 -3
  467. data/app/scripts/generate/bookmarks +0 -3
  468. data/app/scripts/replay +0 -3
  469. data/app/scripts/results +0 -3
  470. data/app/scripts/run +0 -3
  471. data/app/scripts/server +0 -3
  472. data/app/scripts/shell +0 -3
  473. data/app/scripts/test +0 -3
  474. data/app/tasks/.gitattributes +0 -0
  475. data/app/tasks/ROBOT/.gitattributes +0 -0
  476. data/bin/roby-shell +0 -25
  477. data/doc/guide/src/basics/app.page +0 -139
  478. data/doc/guide/src/basics/index.page +0 -11
  479. data/doc/guide/src/basics/log_replay/goForward_1.png +0 -0
  480. data/doc/guide/src/basics/log_replay/goForward_2.png +0 -0
  481. data/doc/guide/src/basics/log_replay/goForward_3.png +0 -0
  482. data/doc/guide/src/basics/log_replay/goForward_5.png +0 -0
  483. data/doc/guide/src/basics/log_replay/plan_repair_4.png +0 -0
  484. data/doc/guide/src/basics/log_replay/roby_log_main_window.png +0 -0
  485. data/doc/guide/src/basics/relations_display.page +0 -203
  486. data/doc/guide/src/basics/shell.page +0 -102
  487. data/doc/guide/src/default.css +0 -319
  488. data/doc/guide/src/introduction/index.page +0 -29
  489. data/doc/guide/src/introduction/publications.page +0 -14
  490. data/doc/guide/src/relations/dependency.page +0 -89
  491. data/doc/guide/src/relations/index.page +0 -12
  492. data/ext/droby/dump.cc +0 -175
  493. data/ext/droby/extconf.rb +0 -3
  494. data/ext/graph/algorithm.cc +0 -746
  495. data/ext/graph/extconf.rb +0 -7
  496. data/ext/graph/graph.cc +0 -575
  497. data/ext/graph/graph.hh +0 -183
  498. data/ext/graph/iterator_sequence.hh +0 -102
  499. data/ext/graph/undirected_dfs.hh +0 -226
  500. data/ext/graph/undirected_graph.hh +0 -421
  501. data/lib/roby/app/scripts/generate/bookmarks.rb +0 -162
  502. data/lib/roby/app/scripts/replay.rb +0 -31
  503. data/lib/roby/app/scripts/server.rb +0 -18
  504. data/lib/roby/basic_object.rb +0 -151
  505. data/lib/roby/config.rb +0 -14
  506. data/lib/roby/distributed.rb +0 -36
  507. data/lib/roby/distributed/base.rb +0 -448
  508. data/lib/roby/distributed/communication.rb +0 -875
  509. data/lib/roby/distributed/connection_space.rb +0 -616
  510. data/lib/roby/distributed/distributed_object.rb +0 -206
  511. data/lib/roby/distributed/drb.rb +0 -62
  512. data/lib/roby/distributed/notifications.rb +0 -531
  513. data/lib/roby/distributed/peer.rb +0 -555
  514. data/lib/roby/distributed/protocol.rb +0 -529
  515. data/lib/roby/distributed/proxy.rb +0 -343
  516. data/lib/roby/distributed/subscription.rb +0 -311
  517. data/lib/roby/distributed/transaction.rb +0 -498
  518. data/lib/roby/external_process_task.rb +0 -225
  519. data/lib/roby/graph.rb +0 -160
  520. data/lib/roby/log.rb +0 -3
  521. data/lib/roby/log/chronicle.rb +0 -303
  522. data/lib/roby/log/console.rb +0 -74
  523. data/lib/roby/log/data_stream.rb +0 -275
  524. data/lib/roby/log/dot.rb +0 -279
  525. data/lib/roby/log/event_stream.rb +0 -161
  526. data/lib/roby/log/file.rb +0 -396
  527. data/lib/roby/log/gui/basic_display.ui +0 -83
  528. data/lib/roby/log/gui/basic_display_ui.rb +0 -89
  529. data/lib/roby/log/gui/chronicle.rb +0 -26
  530. data/lib/roby/log/gui/chronicle_view.rb +0 -40
  531. data/lib/roby/log/gui/chronicle_view.ui +0 -70
  532. data/lib/roby/log/gui/chronicle_view_ui.rb +0 -90
  533. data/lib/roby/log/gui/data_displays.rb +0 -171
  534. data/lib/roby/log/gui/data_displays.ui +0 -155
  535. data/lib/roby/log/gui/data_displays_ui.rb +0 -146
  536. data/lib/roby/log/gui/notifications.rb +0 -26
  537. data/lib/roby/log/gui/relations.rb +0 -269
  538. data/lib/roby/log/gui/relations.ui +0 -123
  539. data/lib/roby/log/gui/relations_ui.rb +0 -120
  540. data/lib/roby/log/gui/relations_view.rb +0 -185
  541. data/lib/roby/log/gui/relations_view.ui +0 -149
  542. data/lib/roby/log/gui/relations_view_ui.rb +0 -144
  543. data/lib/roby/log/gui/replay.rb +0 -366
  544. data/lib/roby/log/gui/replay_controls.rb +0 -206
  545. data/lib/roby/log/gui/replay_controls.ui +0 -282
  546. data/lib/roby/log/gui/replay_controls_ui.rb +0 -249
  547. data/lib/roby/log/gui/runtime.rb +0 -130
  548. data/lib/roby/log/hooks.rb +0 -186
  549. data/lib/roby/log/logger.rb +0 -203
  550. data/lib/roby/log/notifications.rb +0 -244
  551. data/lib/roby/log/plan_rebuilder.rb +0 -468
  552. data/lib/roby/log/relations.rb +0 -1084
  553. data/lib/roby/log/server.rb +0 -547
  554. data/lib/roby/log/sqlite.rb +0 -47
  555. data/lib/roby/log/timings.rb +0 -233
  556. data/lib/roby/plan-object.rb +0 -371
  557. data/lib/roby/planning.rb +0 -13
  558. data/lib/roby/planning/loops.rb +0 -309
  559. data/lib/roby/planning/model.rb +0 -1012
  560. data/lib/roby/planning/task.rb +0 -180
  561. data/lib/roby/query.rb +0 -655
  562. data/lib/roby/relations/conflicts.rb +0 -67
  563. data/lib/roby/relations/dependency.rb +0 -358
  564. data/lib/roby/relations/ensured.rb +0 -19
  565. data/lib/roby/relations/error_handling.rb +0 -22
  566. data/lib/roby/relations/events.rb +0 -7
  567. data/lib/roby/relations/executed_by.rb +0 -208
  568. data/lib/roby/relations/influence.rb +0 -10
  569. data/lib/roby/relations/planned_by.rb +0 -63
  570. data/lib/roby/state/information.rb +0 -55
  571. data/lib/roby/state/state.rb +0 -367
  572. data/lib/roby/task-operations.rb +0 -186
  573. data/lib/roby/task_index.rb +0 -80
  574. data/lib/roby/test/distributed.rb +0 -230
  575. data/lib/roby/test/tasks/simple_task.rb +0 -23
  576. data/lib/roby/transactions.rb +0 -507
  577. data/lib/roby/transactions/proxy.rb +0 -325
  578. data/plugins/fault_injection/History.txt +0 -4
  579. data/plugins/fault_injection/README.txt +0 -34
  580. data/plugins/fault_injection/Rakefile +0 -12
  581. data/plugins/fault_injection/TODO.txt +0 -0
  582. data/plugins/fault_injection/app.rb +0 -52
  583. data/plugins/fault_injection/fault_injection.rb +0 -89
  584. data/plugins/fault_injection/test/test_fault_injection.rb +0 -78
  585. data/plugins/subsystems/README.txt +0 -37
  586. data/plugins/subsystems/Rakefile +0 -13
  587. data/plugins/subsystems/app.rb +0 -182
  588. data/plugins/subsystems/test/app/README +0 -24
  589. data/plugins/subsystems/test/app/Rakefile +0 -8
  590. data/plugins/subsystems/test/app/config/app.yml +0 -71
  591. data/plugins/subsystems/test/app/config/init.rb +0 -12
  592. data/plugins/subsystems/test/app/config/roby.yml +0 -3
  593. data/plugins/subsystems/test/app/planners/main.rb +0 -20
  594. data/plugins/subsystems/test/app/scripts/distributed +0 -3
  595. data/plugins/subsystems/test/app/scripts/replay +0 -3
  596. data/plugins/subsystems/test/app/scripts/results +0 -3
  597. data/plugins/subsystems/test/app/scripts/run +0 -3
  598. data/plugins/subsystems/test/app/scripts/server +0 -3
  599. data/plugins/subsystems/test/app/scripts/shell +0 -3
  600. data/plugins/subsystems/test/app/scripts/test +0 -3
  601. data/plugins/subsystems/test/app/tasks/services.rb +0 -15
  602. data/plugins/subsystems/test/test_subsystems.rb +0 -78
  603. data/test/distributed/test_communication.rb +0 -195
  604. data/test/distributed/test_connection.rb +0 -284
  605. data/test/distributed/test_execution.rb +0 -378
  606. data/test/distributed/test_mixed_plan.rb +0 -341
  607. data/test/distributed/test_plan_notifications.rb +0 -238
  608. data/test/distributed/test_protocol.rb +0 -525
  609. data/test/distributed/test_query.rb +0 -106
  610. data/test/distributed/test_remote_plan.rb +0 -491
  611. data/test/distributed/test_transaction.rb +0 -466
  612. data/test/mockups/external_process +0 -28
  613. data/test/mockups/tasks.rb +0 -27
  614. data/test/planning/test_loops.rb +0 -432
  615. data/test/planning/test_model.rb +0 -427
  616. data/test/planning/test_task.rb +0 -126
  617. data/test/relations/test_conflicts.rb +0 -42
  618. data/test/relations/test_dependency.rb +0 -324
  619. data/test/relations/test_ensured.rb +0 -38
  620. data/test/relations/test_executed_by.rb +0 -224
  621. data/test/relations/test_planned_by.rb +0 -56
  622. data/test/suite_core.rb +0 -29
  623. data/test/suite_distributed.rb +0 -10
  624. data/test/suite_planning.rb +0 -4
  625. data/test/suite_relations.rb +0 -8
  626. data/test/tasks/test_external_process.rb +0 -126
  627. data/test/tasks/test_thread_task.rb +0 -70
  628. data/test/test_bgl.rb +0 -528
  629. data/test/test_event.rb +0 -969
  630. data/test/test_exceptions.rb +0 -591
  631. data/test/test_execution_engine.rb +0 -987
  632. data/test/test_gui.rb +0 -20
  633. data/test/test_interface.rb +0 -43
  634. data/test/test_log.rb +0 -125
  635. data/test/test_log_server.rb +0 -133
  636. data/test/test_plan.rb +0 -418
  637. data/test/test_query.rb +0 -424
  638. data/test/test_relations.rb +0 -260
  639. data/test/test_state.rb +0 -432
  640. data/test/test_support.rb +0 -16
  641. data/test/test_task.rb +0 -1181
  642. data/test/test_testcase.rb +0 -138
  643. data/test/test_transactions.rb +0 -610
  644. data/test/test_transactions_proxy.rb +0 -216
@@ -1,616 +0,0 @@
1
- require 'rinda/ring'
2
- require 'rinda/tuplespace'
3
- require 'utilrb/time/to_hms'
4
- require 'utilrb/kernel/options'
5
- require 'utilrb/socket/tcp_server'
6
-
7
- require 'roby/distributed/drb'
8
- require 'roby/distributed/peer'
9
-
10
- module Roby
11
- module Distributed
12
- # A neighbour is a [name, remote_id] tuple, where +name+ is the name of
13
- # the neighbour and +remote_id+ the RemoteID which describes the remote
14
- # ConnectionSpace, used to connect to it.
15
- class Neighbour
16
- attr_reader :name, :remote_id
17
- def initialize(name, remote_id)
18
- @name, @remote_id = name, remote_id
19
- end
20
-
21
- def connect; Peer.initiate_connection(ConnectionSpace.state, peer) end
22
- def ==(other)
23
- other.kind_of?(Neighbour) &&
24
- (remote_id == other.remote_id)
25
- end
26
- def to_s; "#<Neighbour:#{name} #{remote_id}>" end
27
- def eql?(other); other == self end
28
- end
29
-
30
- # Returns the Peer object for the given ID. +id+ can be either the peer
31
- # RemoteID or its name.
32
- def self.peer(id)
33
- if id.kind_of?(Distributed::RemoteID)
34
- if id == remote_id
35
- Distributed
36
- else
37
- peers[id]
38
- end
39
- elsif id.respond_to?(:to_str)
40
- peers.each_value { |p| return p if p.remote_name == id.to_str }
41
- nil
42
- else
43
- nil
44
- end
45
- end
46
-
47
- # Returns a RemoteID object suitable to represent this plan manager on
48
- # the network.
49
- #
50
- # This makes Roby::Distributed behave like a Peer object
51
- def self.remote_id
52
- if state then state.remote_id
53
- else @__single_remote_id__ ||= RemoteID.new('local', 0)
54
- end
55
- end
56
-
57
- # Returns a Peer::DRoby object which can be used in the dRoby
58
- # connection to represent this plan manager.
59
- #
60
- # This makes Roby::Distributed behave like a Peer object
61
- def self.droby_dump(dest = nil)
62
- if state then state.droby_dump(dest)
63
- else @__single_marshalled_peer__ ||= Peer::DRoby.new('single', remote_id)
64
- end
65
- end
66
-
67
- # Execute the given message without blocking. If a block is given,
68
- # yield the result to that block.
69
- #
70
- # This makes Roby::Distributed behave like a Peer object
71
- def self.transmit(*args)
72
- Roby.once do
73
- result = Distributed.state.send(*args)
74
- yield(result) if block_given?
75
- end
76
- end
77
-
78
- # Execute the given message and wait for its result to be available.
79
- #
80
- # This makes Roby::Distributed behave like a Peer object
81
- def self.call(*args)
82
- Roby.execute do
83
- Distributed.state.send(*args)
84
- end
85
- end
86
-
87
- # True if this plan manager is subscribed to +object+
88
- #
89
- # This makes Roby::Distributed behave like a Peer object
90
- def self.subscribed?(object)
91
- object.subscribed?
92
- end
93
-
94
- # This class manages the connections between this plan manager and the
95
- # remote plan managers
96
- #
97
- # * there is only one reception thread, at which all peers send data
98
- class ConnectionSpace
99
- include DRbUndumped
100
-
101
- # List of discovered neighbours
102
- def neighbours; synchronize { @neighbours.dup } end
103
- # A queue containing all new neighbours
104
- attr_reader :new_neighbours
105
- # A remote_id => Peer map of the connected peers
106
- attr_reader :peers
107
- # A remote_id => thread of the connection threads
108
- #
109
- # See Peer.connection_request and Peer.initiate_connection
110
- attr_reader :pending_connections
111
- # A remote_id => thread of the connection threads
112
- #
113
- # See Peer.connection_request, Peer.initiate_connection and Peer#reconnect
114
- attr_reader :aborted_connections
115
- # The set of peers for which we have lost the link
116
- attr_reader :pending_reconnections
117
- # The period at which we do discovery
118
- attr_reader :discovery_period
119
- # The discovery thread
120
- attr_reader :discovery_thread
121
-
122
- # If we are doing discovery based on Rinda::RingFinger
123
- def ring_discovery?; @ring_discovery end
124
- # The list of broadcasting addresses to search for plan databases
125
- attr_reader :ring_broadcast
126
- # If we are doing discovery based on a central tuplespace
127
- def central_discovery?; !!@discovery_tuplespace end
128
- # The central tuplespace where neighbours are announced
129
- attr_reader :discovery_tuplespace
130
- # Last time a discovery finished
131
- attr_reader :last_discovery
132
- # A condition variable which is signalled to start a new discovery
133
- attr_reader :start_discovery
134
- # A condition variable which is signalled when discovery finishes
135
- attr_reader :finished_discovery
136
-
137
- # The main mutex which is used for synchronization with the discovery
138
- # thread
139
- attr_reader :mutex
140
- def synchronize; mutex.synchronize { yield } end
141
- # The plan we are publishing, usually Roby.plan
142
- attr_reader :plan
143
- # The execution engine tied to +plan+, or nil if there is none
144
- def engine; plan.engine end
145
-
146
- # Our name on the network
147
- attr_reader :name
148
- # The socket on which we listen for incoming connections
149
- attr_reader :server_socket
150
-
151
- # Create a new ConnectionSpace objects. The following options can be provided:
152
- #
153
- # name:: the name of this plan manager. Defaults to <hostname>-<PID>
154
- # period:: the discovery period [default: nil]
155
- # ring_discovery:: whether or not ring discovery should be attempted [default: true]
156
- # ring_broadcast:: the broadcast address for ring discovery
157
- # discovery_tuplespace:: the DRbObject referencing the remote tuplespace which holds references to plan managers [default: nil]
158
- # plan:: the plan this ConnectionSpace acts on. [default: Roby.plan]
159
- # listen_at:: the port at which we should listen for incoming connections [default: 0]
160
- def initialize(options = {})
161
- super()
162
-
163
- options = validate_options options,
164
- :name => "#{Socket.gethostname}-#{Process.pid}", # the name of this host
165
- :period => nil, # the discovery period
166
- :ring_discovery => true, # wether we should do discovery based on Rinda::RingFinger
167
- :ring_broadcast => '', # the broadcast address for discovery
168
- :discovery_tuplespace => nil, # a central tuplespace which lists hosts (including ourselves)
169
- :plan => nil, # the plan we publish, uses Roby.plan if nil
170
- :listen_at => 0 # the port at which we listen for incoming connections
171
-
172
- if options[:ring_discovery] && !options[:period]
173
- raise ArgumentError, "you must provide a discovery period when using ring discovery"
174
- end
175
-
176
- @name = options[:name]
177
- @neighbours = Array.new
178
- @peers = Hash.new
179
- @plan = options[:plan] || Roby.plan
180
- @discovery_period = options[:period]
181
- @ring_discovery = options[:ring_discovery]
182
- @ring_broadcast = options[:ring_broadcast]
183
- @discovery_tuplespace = options[:discovery_tuplespace]
184
- @port = options[:port]
185
- @pending_sockets = Queue.new
186
- @pending_connections = Hash.new
187
- @aborted_connections = Hash.new
188
- @pending_reconnections = Array.new
189
- @quit_neighbour_thread = false
190
-
191
- @mutex = Mutex.new
192
- @start_discovery = ConditionVariable.new
193
- @finished_discovery = ConditionVariable.new
194
- @new_neighbours = Queue.new
195
- @new_neighbours_observers = Array.new
196
-
197
- @connection_listeners = Array.new
198
-
199
- yield(self) if block_given?
200
-
201
- listen(options[:listen_at])
202
- @remote_id = RemoteID.new(Socket.gethostname, server_socket.port)
203
-
204
- if central_discovery?
205
- if (discovery_tuplespace.write([:droby, name, remote_id]) rescue nil)
206
- if discovery_tuplespace.kind_of?(DRbObject)
207
- Distributed.info "published #{name}(#{remote_id}) on #{discovery_tuplespace.__drburi}"
208
- else
209
- Distributed.info "published #{name}(#{remote_id}) on local tuplespace"
210
- end
211
- else
212
- Distributed.warn "cannot connect to #{discovery_tuplespace.__drburi}, disabling centralized discovery"
213
- discovery_tuplespace = nil
214
- end
215
- end
216
-
217
- if ring_discovery?
218
- Distributed.info "doing ring discovery on #{ring_broadcast}"
219
- end
220
-
221
- synchronize do
222
- # Start the discovery thread and wait for it to be initialized
223
- @discovery_thread = Thread.new(&method(:neighbour_discovery))
224
- finished_discovery.wait(mutex)
225
- end
226
- start_neighbour_discovery(true)
227
-
228
- @discovery_start_handler = engine.add_propagation_handler do |plan|
229
- start_neighbour_discovery
230
- notify_new_neighbours
231
- end
232
- engine.finalizers << method(:quit)
233
- engine.at_cycle_end do
234
- peers.each_value do |peer|
235
- if peer.connected?
236
- peer.transmit(:state_update, Roby::State)
237
- end
238
- end
239
- end
240
-
241
- # Finally, start the reception thread
242
- receive
243
- end
244
-
245
- # Sets up a separate thread which listens for connection
246
- def listen(port)
247
- @server_socket = TCPServer.new(nil, port)
248
- server_socket.listen(10)
249
- Thread.new do
250
- begin
251
- while new_connection = server_socket.accept
252
- begin
253
- Peer.connection_request(self, new_connection)
254
- rescue Exception => e
255
- Roby::Distributed.fatal "failed to handle connection request on #{new_connection}"
256
- Roby::Distributed.fatal e.full_message
257
- new_connection.close
258
- end
259
- end
260
- rescue Exception
261
- end
262
- end
263
- end
264
-
265
- # The RemoteID object which allows to reference this ConnectionSpace on the network
266
- attr_reader :remote_id
267
-
268
- # The set of new sockets to wait for. If one of these is closed,
269
- # Distributed.receive will check wether we are supposed to be
270
- # connected to the peer. If it's not the case, the socket will be
271
- # ignored.
272
- attr_reader :pending_sockets
273
-
274
- # Starts the reception thread
275
- def receive # :nodoc:
276
- sockets = Hash.new
277
- Thread.new do
278
- while true
279
- begin
280
- while !pending_sockets.empty?
281
- socket, peer = pending_sockets.shift
282
- sockets[socket] = peer
283
- begin
284
- Roby::Distributed.info "listening to #{socket.peer_info} for #{peer}"
285
- rescue IOError
286
- end
287
- end
288
-
289
- begin
290
- sockets.delete_if { |s, p| s.closed? && p.disconnected? }
291
- read, _, errors = select(sockets.keys, nil, nil, 0.1)
292
- rescue IOError
293
- end
294
- next if !read
295
-
296
- closed_sockets = []
297
- for socket in read
298
- if socket.closed?
299
- closed_sockets << socket
300
- next
301
- end
302
-
303
- begin
304
- header = socket.read(8)
305
- unless header && header.size == 8
306
- closed_sockets << socket
307
- next
308
- end
309
-
310
- id, size = header.unpack("NN")
311
- data = socket.read(size)
312
-
313
- p = sockets[socket]
314
- p.stats.rx += (size + 8)
315
- Roby::Distributed.cycles_rx << [p, Marshal.load(data)]
316
- rescue Errno::ECONNRESET, IOError
317
- closed_sockets << socket
318
- end
319
- end
320
-
321
- for socket in closed_sockets
322
- p = sockets[socket]
323
- if p.connected?
324
- Roby::Distributed.info "lost connection with #{p}"
325
- p.reconnect
326
- sockets.delete socket
327
- elsif p.disconnecting?
328
- Roby::Distributed.info "#{p} disconnected"
329
- p.disconnected
330
- end
331
- end
332
-
333
- rescue Exception
334
- Roby::Distributed.fatal "error in ConnectionSpace#receive: #{$!.full_message}"
335
- end
336
- end
337
- end
338
- end
339
-
340
- def discovering?
341
- synchronize do
342
- if @last_discovery != @discovery_start
343
- yield if block_given?
344
- true
345
- end
346
- end
347
- end
348
-
349
- def owns?(object); object.owners.include?(Roby::Distributed) end
350
-
351
- # An array of procs called at the end of the neighbour discovery,
352
- # after #neighbours have been updated
353
- attr_reader :connection_listeners
354
-
355
- def discovery_port
356
- if Distributed.server
357
- Distributed.server.port
358
- else DISCOVERY_RING_PORT
359
- end
360
- end
361
-
362
- # Loop which does neighbour_discovery
363
- def neighbour_discovery
364
- Thread.current.priority = 2
365
-
366
- discovered = []
367
-
368
- # Initialize so that @discovery_start == discovery_start
369
- @discovery_start = nil
370
- discovery_start = nil
371
- finger = nil
372
- loop do
373
- return if @quit_neighbour_thread
374
-
375
- Roby.synchronize do
376
- old_neighbours, @neighbours = @neighbours, []
377
- for new in discovered
378
- unless new.remote_id == remote_id || @neighbours.include?(new)
379
- @neighbours << new
380
- unless old_neighbours.include?(new)
381
- new_neighbours << [self, new]
382
- end
383
- end
384
- end
385
- discovered.clear
386
- end
387
-
388
- connection_listeners.each { |listen| listen.call(self) }
389
- synchronize do
390
- @last_discovery = discovery_start
391
- finished_discovery.broadcast
392
-
393
- if @discovery_start == @last_discovery
394
- start_discovery.wait(mutex)
395
- end
396
- return if @quit_neighbour_thread
397
- discovery_start = @discovery_start
398
- end
399
-
400
- from = Time.now
401
- if ring_discovery? && (!finger || (finger.port != discovery_port))
402
- finger = Rinda::RingFinger.new(ring_broadcast, discovery_port)
403
- end
404
- if central_discovery?
405
- discovery_tuplespace.read_all([:droby, nil, nil]).
406
- each do |n|
407
- next if n[2] == remote_id
408
- n = Neighbour.new(n[1], n[2])
409
- discovered << n
410
- end
411
- end
412
-
413
- if ring_discovery?
414
- if discovery_period
415
- remaining = (@discovery_start + discovery_period) - Time.now
416
- end
417
-
418
- finger.lookup_ring(remaining) do |cs|
419
- next if cs == self
420
-
421
- discovered << Neighbour.new(cs.name, cs.remote_id)
422
- end
423
- end
424
- end
425
-
426
- rescue Interrupt
427
- rescue Exception => e
428
- Distributed.fatal "neighbour discovery died with\n#{e.full_message}"
429
- Distributed.fatal "Peers are: #{Distributed.peers.map { |id, peer| "#{id.inspect} => #{peer}" }.join(", ")}"
430
-
431
- ensure
432
- Distributed.info "quit neighbour thread"
433
- neighbours.clear
434
- new_neighbours.clear
435
-
436
- # Force disconnection in case something got wrong in the normal
437
- # disconnection process
438
- Distributed.peers.values.each do |peer|
439
- peer.disconnected! unless peer.disconnected?
440
- end
441
-
442
- synchronize do
443
- @discovery_thread = nil
444
- finished_discovery.broadcast
445
- end
446
- end
447
-
448
- # Starts one neighbour discovery loop
449
- def start_neighbour_discovery(block = false)
450
- synchronize do
451
- unless discovery_thread && discovery_thread.alive?
452
- raise "no discovery thread"
453
- end
454
-
455
- @discovery_start = Time.now
456
- start_discovery.broadcast
457
- end
458
- wait_discovery if block
459
- end
460
-
461
- def wait_discovery
462
- discovering? do
463
- finished_discovery.wait(mutex)
464
- end
465
- end
466
- def wait_next_discovery
467
- synchronize do
468
- unless discovery_thread && discovery_thread.alive?
469
- raise "no discovery thread"
470
- end
471
- finished_discovery.wait(mutex)
472
- end
473
- end
474
-
475
- # Define #droby_dump for Peer-like behaviour
476
- def droby_dump(dest = nil); @__droby_marshalled__ ||= Peer::DRoby.new(name, remote_id) end
477
-
478
- # Make the ConnectionSpace quit
479
- def quit
480
- Distributed.debug "ConnectionSpace #{self} quitting"
481
- if @discovery_start_handler
482
- engine.remove_propagation_handler(@discovery_start_handler)
483
- end
484
-
485
- # Remove us from the central tuplespace
486
- if central_discovery?
487
- begin
488
- discovery_tuplespace.take [:droby, nil, remote_id], 0
489
- rescue DRb::DRbConnError, Rinda::RequestExpiredError
490
- end
491
- end
492
-
493
- # Make the neighbour discovery thread quit as well
494
- thread = synchronize do
495
- if thread = @discovery_thread
496
- thread.raise Interrupt, "forcing discovery thread quit"
497
- end
498
- thread
499
- end
500
- if thread
501
- thread.join
502
- end
503
-
504
- ensure
505
- if server_socket
506
- begin
507
- server_socket.close
508
- rescue IOError
509
- end
510
- end
511
-
512
- plan.engine.finalizers.delete(method(:quit))
513
- if Distributed.state == self
514
- Distributed.state = nil
515
- end
516
- end
517
-
518
- # Disable the keeper thread, we will do cleanup ourselves
519
- def start_keeper; end
520
-
521
- # This makes ConnectionSpace act as a PeerServer object locally
522
- def transaction_prepare_commit(trsc) # :nodoc:
523
- !trsc.valid_transaction?
524
- end
525
- # This makes ConnectionSpace act as a PeerServer object locally
526
- def transaction_abandon_commit(trsc, reason) # :nodoc:
527
- trsc.abandoned_commit(reason)
528
- end
529
- # This makes ConnectionSpace act as a PeerServer object locally
530
- def transaction_commit(trsc) # :nodoc:
531
- trsc.commit_transaction(false)
532
- end
533
- # This makes ConnectionSpace act as a PeerServer object locally
534
- def transaction_discard(trsc) # :nodoc:
535
- trsc.discard_transaction(false)
536
- end
537
-
538
- def on_neighbour
539
- current = neighbours.dup
540
- engine.once { current.each { |n| yield(n) } }
541
- new_neighbours_observers << lambda { |_, n| yield(n) }
542
- end
543
-
544
- # The set of proc objects which should be notified when new
545
- # neighbours are detected.
546
- attr_reader :new_neighbours_observers
547
-
548
- # Called in the neighbour discovery thread to detect new
549
- # neighbours. It fills the new_neighbours queue which is read by
550
- # notify_new_neighbours to notify application code of new
551
- # neighbours in the control thread
552
- def notify_new_neighbours
553
- while !new_neighbours.empty?
554
- cs, neighbour = new_neighbours.pop(true)
555
- new_neighbours_observers.each do |obs|
556
- obs[cs, neighbour]
557
- end
558
- end
559
- end
560
-
561
- end
562
-
563
- class << self
564
- # The RingServer object through which we publish this plan manager
565
- # on the network
566
- attr_reader :server
567
-
568
- # True if we are published on the network.
569
- #
570
- # See #server, #publish and #unpublish
571
- def published?; !!@server end
572
-
573
- # Enable ring discovery on our part. A RingServer object is set up
574
- # to listen to connections on the port given as a :port option (or
575
- # DISCOVERY_RING_PORT if none is specified).
576
- #
577
- # Note that all plan managers must use the same discovery port.
578
- def publish(options = {})
579
- options[:port] ||= DISCOVERY_RING_PORT
580
- @server = RingServer.new(state, options)
581
- Distributed.info "listening for distributed discovery on #{options[:port]}"
582
- end
583
-
584
- # Disable the ring discovery on our part.
585
- def unpublish
586
- if server
587
- server.close
588
- @server = nil
589
- Distributed.info "disabled distributed discovery"
590
- end
591
- end
592
-
593
- # The list of known neighbours. See ConnectionSpace#neighbours
594
- def neighbours
595
- if state then state.neighbours
596
- else []
597
- end
598
- end
599
-
600
- # The list of neighbours that have been found since the last
601
- # execution cycle
602
- def new_neighbours
603
- if state then state.new_neighbours
604
- else []
605
- end
606
- end
607
-
608
- # Defines a block which should be called when a new neighbour is
609
- # detected
610
- #
611
- # See ConnectionSpace#on_neighbour
612
- def on_neighbour(&block); Roby::Distributed.state.on_neighbour(&block) end
613
- end
614
- end
615
- end
616
-