roby 0.7
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.
- data/.gitignore +29 -0
- data/History.txt +4 -0
- data/License-fr.txt +519 -0
- data/License.txt +515 -0
- data/Manifest.txt +245 -0
- data/NOTES +4 -0
- data/README.txt +163 -0
- data/Rakefile +161 -0
- data/TODO.txt +146 -0
- data/app/README.txt +24 -0
- data/app/Rakefile +8 -0
- data/app/config/ROBOT.rb +5 -0
- data/app/config/app.yml +91 -0
- data/app/config/init.rb +7 -0
- data/app/config/roby.yml +3 -0
- data/app/controllers/.gitattributes +0 -0
- data/app/controllers/ROBOT.rb +2 -0
- data/app/data/.gitattributes +0 -0
- data/app/planners/ROBOT/main.rb +6 -0
- data/app/planners/main.rb +5 -0
- data/app/scripts/distributed +3 -0
- data/app/scripts/generate/bookmarks +3 -0
- data/app/scripts/replay +3 -0
- data/app/scripts/results +3 -0
- data/app/scripts/run +3 -0
- data/app/scripts/server +3 -0
- data/app/scripts/shell +3 -0
- data/app/scripts/test +3 -0
- data/app/tasks/.gitattributes +0 -0
- data/app/tasks/ROBOT/.gitattributes +0 -0
- data/bin/roby +210 -0
- data/bin/roby-log +168 -0
- data/bin/roby-shell +25 -0
- data/doc/images/event_generalization.png +0 -0
- data/doc/images/exception_propagation_1.png +0 -0
- data/doc/images/exception_propagation_2.png +0 -0
- data/doc/images/exception_propagation_3.png +0 -0
- data/doc/images/exception_propagation_4.png +0 -0
- data/doc/images/exception_propagation_5.png +0 -0
- data/doc/images/replay_handler_error.png +0 -0
- data/doc/images/replay_handler_error_0.png +0 -0
- data/doc/images/replay_handler_error_1.png +0 -0
- data/doc/images/roby_cycle_overview.png +0 -0
- data/doc/images/roby_replay_02.png +0 -0
- data/doc/images/roby_replay_03.png +0 -0
- data/doc/images/roby_replay_04.png +0 -0
- data/doc/images/roby_replay_event_representation.png +0 -0
- data/doc/images/roby_replay_first_state.png +0 -0
- data/doc/images/roby_replay_relations.png +0 -0
- data/doc/images/roby_replay_startup.png +0 -0
- data/doc/images/task_event_generalization.png +0 -0
- data/doc/papers.rdoc +11 -0
- data/doc/styles/allison.css +314 -0
- data/doc/styles/allison.js +316 -0
- data/doc/styles/allison.rb +276 -0
- data/doc/styles/jamis.rb +593 -0
- data/doc/tutorials/01-GettingStarted.rdoc +86 -0
- data/doc/tutorials/02-GoForward.rdoc +220 -0
- data/doc/tutorials/03-PlannedPath.rdoc +268 -0
- data/doc/tutorials/04-EventPropagation.rdoc +236 -0
- data/doc/tutorials/05-ErrorHandling.rdoc +319 -0
- data/doc/tutorials/06-Overview.rdoc +40 -0
- data/doc/videos.rdoc +69 -0
- data/ext/droby/dump.cc +175 -0
- data/ext/droby/extconf.rb +3 -0
- data/ext/graph/algorithm.cc +746 -0
- data/ext/graph/extconf.rb +7 -0
- data/ext/graph/graph.cc +529 -0
- data/ext/graph/graph.hh +183 -0
- data/ext/graph/iterator_sequence.hh +102 -0
- data/ext/graph/undirected_dfs.hh +226 -0
- data/ext/graph/undirected_graph.hh +421 -0
- data/lib/roby.rb +41 -0
- data/lib/roby/app.rb +870 -0
- data/lib/roby/app/rake.rb +56 -0
- data/lib/roby/app/run.rb +14 -0
- data/lib/roby/app/scripts/distributed.rb +13 -0
- data/lib/roby/app/scripts/generate/bookmarks.rb +162 -0
- data/lib/roby/app/scripts/replay.rb +31 -0
- data/lib/roby/app/scripts/results.rb +15 -0
- data/lib/roby/app/scripts/run.rb +26 -0
- data/lib/roby/app/scripts/server.rb +18 -0
- data/lib/roby/app/scripts/shell.rb +88 -0
- data/lib/roby/app/scripts/test.rb +40 -0
- data/lib/roby/basic_object.rb +151 -0
- data/lib/roby/config.rb +5 -0
- data/lib/roby/control.rb +747 -0
- data/lib/roby/decision_control.rb +17 -0
- data/lib/roby/distributed.rb +32 -0
- data/lib/roby/distributed/base.rb +440 -0
- data/lib/roby/distributed/communication.rb +871 -0
- data/lib/roby/distributed/connection_space.rb +592 -0
- data/lib/roby/distributed/distributed_object.rb +206 -0
- data/lib/roby/distributed/drb.rb +62 -0
- data/lib/roby/distributed/notifications.rb +539 -0
- data/lib/roby/distributed/peer.rb +550 -0
- data/lib/roby/distributed/protocol.rb +529 -0
- data/lib/roby/distributed/proxy.rb +343 -0
- data/lib/roby/distributed/subscription.rb +311 -0
- data/lib/roby/distributed/transaction.rb +498 -0
- data/lib/roby/event.rb +897 -0
- data/lib/roby/exceptions.rb +234 -0
- data/lib/roby/executives/simple.rb +30 -0
- data/lib/roby/graph.rb +166 -0
- data/lib/roby/interface.rb +390 -0
- data/lib/roby/log.rb +3 -0
- data/lib/roby/log/chronicle.rb +303 -0
- data/lib/roby/log/console.rb +72 -0
- data/lib/roby/log/data_stream.rb +197 -0
- data/lib/roby/log/dot.rb +279 -0
- data/lib/roby/log/event_stream.rb +151 -0
- data/lib/roby/log/file.rb +340 -0
- data/lib/roby/log/gui/basic_display.ui +83 -0
- data/lib/roby/log/gui/chronicle.rb +26 -0
- data/lib/roby/log/gui/chronicle_view.rb +40 -0
- data/lib/roby/log/gui/chronicle_view.ui +70 -0
- data/lib/roby/log/gui/data_displays.rb +172 -0
- data/lib/roby/log/gui/data_displays.ui +155 -0
- data/lib/roby/log/gui/notifications.rb +26 -0
- data/lib/roby/log/gui/relations.rb +248 -0
- data/lib/roby/log/gui/relations.ui +123 -0
- data/lib/roby/log/gui/relations_view.rb +185 -0
- data/lib/roby/log/gui/relations_view.ui +149 -0
- data/lib/roby/log/gui/replay.rb +327 -0
- data/lib/roby/log/gui/replay_controls.rb +200 -0
- data/lib/roby/log/gui/replay_controls.ui +259 -0
- data/lib/roby/log/gui/runtime.rb +130 -0
- data/lib/roby/log/hooks.rb +185 -0
- data/lib/roby/log/logger.rb +202 -0
- data/lib/roby/log/notifications.rb +244 -0
- data/lib/roby/log/plan_rebuilder.rb +470 -0
- data/lib/roby/log/relations.rb +1056 -0
- data/lib/roby/log/server.rb +550 -0
- data/lib/roby/log/sqlite.rb +47 -0
- data/lib/roby/log/timings.rb +164 -0
- data/lib/roby/plan-object.rb +247 -0
- data/lib/roby/plan.rb +762 -0
- data/lib/roby/planning.rb +13 -0
- data/lib/roby/planning/loops.rb +302 -0
- data/lib/roby/planning/model.rb +906 -0
- data/lib/roby/planning/task.rb +151 -0
- data/lib/roby/propagation.rb +562 -0
- data/lib/roby/query.rb +619 -0
- data/lib/roby/relations.rb +583 -0
- data/lib/roby/relations/conflicts.rb +70 -0
- data/lib/roby/relations/ensured.rb +20 -0
- data/lib/roby/relations/error_handling.rb +23 -0
- data/lib/roby/relations/events.rb +9 -0
- data/lib/roby/relations/executed_by.rb +193 -0
- data/lib/roby/relations/hierarchy.rb +239 -0
- data/lib/roby/relations/influence.rb +10 -0
- data/lib/roby/relations/planned_by.rb +63 -0
- data/lib/roby/robot.rb +7 -0
- data/lib/roby/standard_errors.rb +218 -0
- data/lib/roby/state.rb +5 -0
- data/lib/roby/state/events.rb +221 -0
- data/lib/roby/state/information.rb +55 -0
- data/lib/roby/state/pos.rb +110 -0
- data/lib/roby/state/shapes.rb +32 -0
- data/lib/roby/state/state.rb +353 -0
- data/lib/roby/support.rb +92 -0
- data/lib/roby/task-operations.rb +182 -0
- data/lib/roby/task.rb +1618 -0
- data/lib/roby/test/common.rb +399 -0
- data/lib/roby/test/distributed.rb +214 -0
- data/lib/roby/test/tasks/empty_task.rb +9 -0
- data/lib/roby/test/tasks/goto.rb +36 -0
- data/lib/roby/test/tasks/simple_task.rb +23 -0
- data/lib/roby/test/testcase.rb +519 -0
- data/lib/roby/test/tools.rb +160 -0
- data/lib/roby/thread_task.rb +87 -0
- data/lib/roby/transactions.rb +462 -0
- data/lib/roby/transactions/proxy.rb +292 -0
- data/lib/roby/transactions/updates.rb +139 -0
- data/plugins/fault_injection/History.txt +4 -0
- data/plugins/fault_injection/README.txt +37 -0
- data/plugins/fault_injection/Rakefile +18 -0
- data/plugins/fault_injection/TODO.txt +0 -0
- data/plugins/fault_injection/app.rb +52 -0
- data/plugins/fault_injection/fault_injection.rb +89 -0
- data/plugins/fault_injection/test/test_fault_injection.rb +84 -0
- data/plugins/subsystems/README.txt +40 -0
- data/plugins/subsystems/Rakefile +18 -0
- data/plugins/subsystems/app.rb +171 -0
- data/plugins/subsystems/test/app/README +24 -0
- data/plugins/subsystems/test/app/Rakefile +8 -0
- data/plugins/subsystems/test/app/config/app.yml +71 -0
- data/plugins/subsystems/test/app/config/init.rb +9 -0
- data/plugins/subsystems/test/app/config/roby.yml +3 -0
- data/plugins/subsystems/test/app/planners/main.rb +20 -0
- data/plugins/subsystems/test/app/scripts/distributed +3 -0
- data/plugins/subsystems/test/app/scripts/replay +3 -0
- data/plugins/subsystems/test/app/scripts/results +3 -0
- data/plugins/subsystems/test/app/scripts/run +3 -0
- data/plugins/subsystems/test/app/scripts/server +3 -0
- data/plugins/subsystems/test/app/scripts/shell +3 -0
- data/plugins/subsystems/test/app/scripts/test +3 -0
- data/plugins/subsystems/test/app/tasks/services.rb +15 -0
- data/plugins/subsystems/test/test_subsystems.rb +71 -0
- data/test/distributed/test_communication.rb +178 -0
- data/test/distributed/test_connection.rb +282 -0
- data/test/distributed/test_execution.rb +373 -0
- data/test/distributed/test_mixed_plan.rb +341 -0
- data/test/distributed/test_plan_notifications.rb +238 -0
- data/test/distributed/test_protocol.rb +516 -0
- data/test/distributed/test_query.rb +102 -0
- data/test/distributed/test_remote_plan.rb +491 -0
- data/test/distributed/test_transaction.rb +463 -0
- data/test/mockups/tasks.rb +27 -0
- data/test/planning/test_loops.rb +380 -0
- data/test/planning/test_model.rb +427 -0
- data/test/planning/test_task.rb +106 -0
- data/test/relations/test_conflicts.rb +42 -0
- data/test/relations/test_ensured.rb +38 -0
- data/test/relations/test_executed_by.rb +149 -0
- data/test/relations/test_hierarchy.rb +158 -0
- data/test/relations/test_planned_by.rb +54 -0
- data/test/suite_core.rb +24 -0
- data/test/suite_distributed.rb +9 -0
- data/test/suite_planning.rb +3 -0
- data/test/suite_relations.rb +8 -0
- data/test/test_bgl.rb +508 -0
- data/test/test_control.rb +399 -0
- data/test/test_event.rb +894 -0
- data/test/test_exceptions.rb +592 -0
- data/test/test_interface.rb +37 -0
- data/test/test_log.rb +114 -0
- data/test/test_log_server.rb +132 -0
- data/test/test_plan.rb +584 -0
- data/test/test_propagation.rb +210 -0
- data/test/test_query.rb +266 -0
- data/test/test_relations.rb +180 -0
- data/test/test_state.rb +414 -0
- data/test/test_support.rb +16 -0
- data/test/test_task.rb +938 -0
- data/test/test_testcase.rb +122 -0
- data/test/test_thread_task.rb +73 -0
- data/test/test_transactions.rb +569 -0
- data/test/test_transactions_proxy.rb +198 -0
- metadata +570 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
require 'Qt4'
|
|
2
|
+
require 'roby/app'
|
|
3
|
+
|
|
4
|
+
require 'roby/log/gui/replay_controls_ui'
|
|
5
|
+
require 'roby/log/gui/data_displays'
|
|
6
|
+
require 'roby/log/server'
|
|
7
|
+
|
|
8
|
+
class RemoteStreamListModel < DataStreamListModel
|
|
9
|
+
attr_reader :known_servers
|
|
10
|
+
def initialize(streams)
|
|
11
|
+
super
|
|
12
|
+
@known_servers = []
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Update the list of available servers and streams
|
|
16
|
+
def update
|
|
17
|
+
Roby::Log::Server.available_servers.each do |server|
|
|
18
|
+
unless known_servers.find { |str| str.server == server }
|
|
19
|
+
begin
|
|
20
|
+
known_servers << Roby::Log::Client.new(server)
|
|
21
|
+
rescue DRb::DRbConnError
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
known_servers.delete_if { |s| !s.connected? }
|
|
27
|
+
|
|
28
|
+
found_streams = []
|
|
29
|
+
known_servers.delete_if do |server|
|
|
30
|
+
begin
|
|
31
|
+
server.streams.each do |stream|
|
|
32
|
+
found_streams << stream
|
|
33
|
+
unless streams.include?(stream)
|
|
34
|
+
server.subscribe(stream)
|
|
35
|
+
add_new(stream)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
false
|
|
39
|
+
rescue DRb::DRbConnError
|
|
40
|
+
s.disconnect
|
|
41
|
+
true
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
(streams - found_streams).each do |s|
|
|
46
|
+
row = streams.index(s)
|
|
47
|
+
removeRow(row, Qt::ModelIndex.new)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
class RuntimeDisplay < Qt::MainWindow
|
|
53
|
+
attr_reader :ui_displays
|
|
54
|
+
|
|
55
|
+
attr_reader :streams
|
|
56
|
+
attr_reader :streams_model
|
|
57
|
+
|
|
58
|
+
DISPLAY_MINIMUM_DURATION = 5
|
|
59
|
+
|
|
60
|
+
def initialize(broadcast, port, period)
|
|
61
|
+
super()
|
|
62
|
+
|
|
63
|
+
# Create the vertical layout for this window
|
|
64
|
+
central_widget = Qt::Widget.new(self)
|
|
65
|
+
self.central_widget = central_widget
|
|
66
|
+
layout = Qt::VBoxLayout.new(central_widget)
|
|
67
|
+
layout.spacing = 6
|
|
68
|
+
layout.margin = 0
|
|
69
|
+
|
|
70
|
+
# add GUI for the data streams and display setup
|
|
71
|
+
@streams = Array.new
|
|
72
|
+
@streams_model = RemoteStreamListModel.new(streams)
|
|
73
|
+
displays_holder = Qt::Widget.new(central_widget)
|
|
74
|
+
layout.add_widget displays_holder
|
|
75
|
+
@ui_displays = Ui_DataDisplays.new
|
|
76
|
+
ui_displays.setupUi(displays_holder)
|
|
77
|
+
ui_displays.streams.model = streams_model
|
|
78
|
+
ui_displays.add_stream.enabled = false
|
|
79
|
+
ui_displays.remove_stream.enabled = false
|
|
80
|
+
connect(ui_displays.display_add, SIGNAL("clicked()"), self, SLOT("add_display()"))
|
|
81
|
+
|
|
82
|
+
# Set up the stream discovery
|
|
83
|
+
Roby::Log::Server.enable_discovery(broadcast, port, period)
|
|
84
|
+
|
|
85
|
+
# This timer is used to call Thread.pass ... of course needed or Ruby
|
|
86
|
+
# threads won't be woken up
|
|
87
|
+
Thread.current.priority = -1
|
|
88
|
+
|
|
89
|
+
@threads_timer = Qt::Timer.new(self)
|
|
90
|
+
connect(@threads_timer, SIGNAL('timeout()')) do
|
|
91
|
+
Thread.pass
|
|
92
|
+
end
|
|
93
|
+
@threads_timer.start(50)
|
|
94
|
+
|
|
95
|
+
@display_timer = Qt::Timer.new(self)
|
|
96
|
+
connect(@display_timer, SIGNAL('timeout()')) do
|
|
97
|
+
streams.each do |s|
|
|
98
|
+
s.synchronize do
|
|
99
|
+
s.display
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
@display_timer.start(5000)
|
|
104
|
+
|
|
105
|
+
sleep(0.5)
|
|
106
|
+
streams_model.update
|
|
107
|
+
|
|
108
|
+
@discovery_timer = Qt::Timer.new(self)
|
|
109
|
+
connect(@discovery_timer, SIGNAL('timeout()')) do
|
|
110
|
+
streams_model.update
|
|
111
|
+
end
|
|
112
|
+
@discovery_timer.start(Integer(period * 1000))
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def add_display(kind = nil)
|
|
116
|
+
ui_displays.add_display(streams_model, kind)
|
|
117
|
+
end
|
|
118
|
+
slots 'add_display()'
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
if $0 == __FILE__
|
|
122
|
+
DRb.start_service "druby://:0"
|
|
123
|
+
Roby::Log::Server.logger.level = Logger::DEBUG
|
|
124
|
+
|
|
125
|
+
a = Qt::Application.new(ARGV)
|
|
126
|
+
w = RuntimeDisplay.new('localhost', Roby::Log::Server::RING_PORT, 5)
|
|
127
|
+
w.show
|
|
128
|
+
a.exec
|
|
129
|
+
end
|
|
130
|
+
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
require 'roby/log/logger'
|
|
2
|
+
require 'roby'
|
|
3
|
+
|
|
4
|
+
module Roby::Log
|
|
5
|
+
module BasicObjectHooks
|
|
6
|
+
HOOKS = %w{added_owner removed_owner}
|
|
7
|
+
|
|
8
|
+
def added_owner(peer)
|
|
9
|
+
super if defined? super
|
|
10
|
+
Roby::Log.log(:added_owner) { [self, peer] }
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def removed_owner(peer)
|
|
14
|
+
super if defined? super
|
|
15
|
+
Roby::Log.log(:removed_owner) { [self, peer] }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
Roby::BasicObject.include BasicObjectHooks
|
|
19
|
+
|
|
20
|
+
module TaskHooks
|
|
21
|
+
HOOKS = %w{added_task_child removed_task_child}
|
|
22
|
+
|
|
23
|
+
def added_child_object(child, relations, info)
|
|
24
|
+
super if defined? super
|
|
25
|
+
Roby::Log.log(:added_task_child) { [self, relations, child, info] }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def removed_child_object(child, relations)
|
|
29
|
+
super if defined? super
|
|
30
|
+
Roby::Log.log(:removed_task_child) { [self, relations, child] }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
Roby::Task.include TaskHooks
|
|
34
|
+
|
|
35
|
+
module PlanHooks
|
|
36
|
+
HOOKS = %w{inserted_tasks discarded_tasks replaced_tasks
|
|
37
|
+
discovered_tasks discovered_events
|
|
38
|
+
garbage_task finalized_task finalized_event
|
|
39
|
+
added_transaction removed_transaction}
|
|
40
|
+
|
|
41
|
+
def inserted(tasks)
|
|
42
|
+
super if defined? super
|
|
43
|
+
Roby::Log.log(:inserted_tasks) { [self, tasks] }
|
|
44
|
+
end
|
|
45
|
+
def discarded(tasks)
|
|
46
|
+
super if defined? super
|
|
47
|
+
Roby::Log.log(:discarded_tasks) { [self, tasks] }
|
|
48
|
+
end
|
|
49
|
+
def replaced(from, to)
|
|
50
|
+
super if defined? super
|
|
51
|
+
Roby::Log.log(:replaced_tasks) { [self, from, to] }
|
|
52
|
+
end
|
|
53
|
+
def discovered_events(tasks)
|
|
54
|
+
super if defined? super
|
|
55
|
+
Roby::Log.log(:discovered_events) { [self, tasks] }
|
|
56
|
+
end
|
|
57
|
+
def discovered_tasks(tasks)
|
|
58
|
+
super if defined? super
|
|
59
|
+
Roby::Log.log(:discovered_tasks) { [self, tasks] }
|
|
60
|
+
end
|
|
61
|
+
def garbage(task)
|
|
62
|
+
super if defined? super
|
|
63
|
+
Roby::Log.log(:garbage_task) { [self, task] }
|
|
64
|
+
end
|
|
65
|
+
def finalized_event(event)
|
|
66
|
+
super if defined? super
|
|
67
|
+
Roby::Log.log(:finalized_event) { [self, event] }
|
|
68
|
+
end
|
|
69
|
+
def finalized_task(task)
|
|
70
|
+
super if defined? super
|
|
71
|
+
Roby::Log.log(:finalized_task) { [self, task] }
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def added_transaction(trsc)
|
|
75
|
+
super if defined? super
|
|
76
|
+
Roby::Log.log(:added_transaction) { [self, trsc] }
|
|
77
|
+
end
|
|
78
|
+
def removed_transaction(trsc)
|
|
79
|
+
super if defined? super
|
|
80
|
+
Roby::Log.log(:removed_transaction) { [self, trsc] }
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
Roby::Plan.include PlanHooks
|
|
84
|
+
|
|
85
|
+
module TransactionHooks
|
|
86
|
+
HOOKS = %w{committed_transaction discarded_transaction}
|
|
87
|
+
|
|
88
|
+
def committed_transaction
|
|
89
|
+
super if defined? super
|
|
90
|
+
Roby::Log.log(:committed_transaction) { [self] }
|
|
91
|
+
end
|
|
92
|
+
def discarded_transaction
|
|
93
|
+
super if defined? super
|
|
94
|
+
Roby::Log.log(:discarded_transaction) { [self] }
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
Roby::Transaction.include TransactionHooks
|
|
98
|
+
|
|
99
|
+
module EventGeneratorHooks
|
|
100
|
+
HOOKS = %w{added_event_child removed_event_child
|
|
101
|
+
generator_calling generator_called generator_fired
|
|
102
|
+
generator_signalling generator_forwarding generator_emitting
|
|
103
|
+
generator_postponed}
|
|
104
|
+
|
|
105
|
+
def added_child_object(to, relations, info)
|
|
106
|
+
super if defined? super
|
|
107
|
+
Roby::Log.log(:added_event_child) { [self, relations, to, info] }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def removed_child_object(to, relations)
|
|
111
|
+
super if defined? super
|
|
112
|
+
Roby::Log.log(:removed_event_child) { [self, relations, to] }
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def calling(context)
|
|
116
|
+
super if defined? super
|
|
117
|
+
Roby::Log.log(:generator_calling) { [self, Roby::Propagation.source_generators, context.to_s] }
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def called(context)
|
|
121
|
+
super if defined? super
|
|
122
|
+
Roby::Log.log(:generator_called) { [self, context.to_s] }
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def fired(event)
|
|
126
|
+
super if defined? super
|
|
127
|
+
Roby::Log.log(:generator_fired) { [self, event.object_id, event.time, event.context.to_s] }
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def signalling(event, to)
|
|
131
|
+
super if defined? super
|
|
132
|
+
Roby::Log.log(:generator_signalling) { [false, self, to, event.object_id, event.time, event.context.to_s] }
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def emitting(context)
|
|
136
|
+
super if defined? super
|
|
137
|
+
Roby::Log.log(:generator_emitting) { [self, Roby::Propagation.source_generators, context.to_s] }
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def forwarding(event, to)
|
|
141
|
+
super if defined? super
|
|
142
|
+
Roby::Log.log(:generator_forwarding) { [true, self, to, event.object_id, event.time, event.context.to_s] }
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def postponed(context, generator, reason)
|
|
146
|
+
super if defined? super
|
|
147
|
+
Roby::Log.log(:generator_postponed) { [self, context.to_s, generator, reason.to_s] }
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
Roby::EventGenerator.include EventGeneratorHooks
|
|
151
|
+
|
|
152
|
+
module ControlHooks
|
|
153
|
+
HOOKS = %w{cycle_end}
|
|
154
|
+
|
|
155
|
+
def cycle_end(timings)
|
|
156
|
+
super if defined? super
|
|
157
|
+
Roby::Log.log(:cycle_end) { [timings] }
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
module ClassExtension
|
|
161
|
+
HOOKS = %w{fatal_exception handled_exception}
|
|
162
|
+
|
|
163
|
+
def fatal_exception(error, tasks)
|
|
164
|
+
super if defined? super
|
|
165
|
+
Roby::Log.log(:fatal_exception) { [error.exception, tasks] }
|
|
166
|
+
end
|
|
167
|
+
def handled_exception(error, task)
|
|
168
|
+
super if defined? super
|
|
169
|
+
Roby::Log.log(:handled_exception) { [error.exception, task] }
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
Roby::Control.include ControlHooks
|
|
174
|
+
|
|
175
|
+
def self.each_hook
|
|
176
|
+
[TransactionHooks, BasicObjectHooks, TaskHooks,
|
|
177
|
+
PlanHooks, EventGeneratorHooks, ControlHooks,
|
|
178
|
+
ControlHooks::ClassExtension].each do |klass|
|
|
179
|
+
klass::HOOKS.each do |m|
|
|
180
|
+
yield(klass, m.to_sym)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
require 'roby/log/hooks'
|
|
2
|
+
require 'roby/log/file'
|
|
3
|
+
|
|
4
|
+
module Roby::Log
|
|
5
|
+
@loggers = Array.new
|
|
6
|
+
@@logging_thread = nil
|
|
7
|
+
|
|
8
|
+
extend Logger::Hierarchy
|
|
9
|
+
extend Logger::Forward
|
|
10
|
+
|
|
11
|
+
class << self
|
|
12
|
+
# Start the logging framework
|
|
13
|
+
def logging?
|
|
14
|
+
@@logging_thread
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Start the logging framework
|
|
18
|
+
def start_logging # :nodoc:
|
|
19
|
+
return if logging?
|
|
20
|
+
logged_events.clear
|
|
21
|
+
@@logging_thread = Thread.new(&method(:logger_loop))
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Stop the logging framework
|
|
25
|
+
def stop_logging # :nodoc:
|
|
26
|
+
return unless logging?
|
|
27
|
+
logged_events.push nil
|
|
28
|
+
flushed_logger_mutex.synchronize do
|
|
29
|
+
while @@logging_thread
|
|
30
|
+
flushed_logger.wait(flushed_logger_mutex)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Add a logger object in the system
|
|
36
|
+
def add_logger(logger)
|
|
37
|
+
start_logging
|
|
38
|
+
@loggers << logger
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Remove a logger from the list of loggers
|
|
42
|
+
def remove_logger(logger)
|
|
43
|
+
flush if logging?
|
|
44
|
+
if @loggers.size == 1
|
|
45
|
+
stop_logging
|
|
46
|
+
end
|
|
47
|
+
@loggers.delete logger
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Remove all loggers
|
|
51
|
+
def clear_loggers
|
|
52
|
+
stop_logging
|
|
53
|
+
@loggers.clear
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Iterates on all the logger objects. If +m+ is given, yields only the loggers
|
|
57
|
+
# which respond to this method.
|
|
58
|
+
def each_logger(m = nil)
|
|
59
|
+
for l in @loggers
|
|
60
|
+
if !m || l.respond_to?(m)
|
|
61
|
+
yield(l)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Returns true if there is at least one loggr for the +m+ message
|
|
67
|
+
def has_logger?(m)
|
|
68
|
+
for l in @loggers
|
|
69
|
+
return true if l.respond_to?(m)
|
|
70
|
+
end
|
|
71
|
+
false
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
attr_reader :logged_events
|
|
75
|
+
attr_reader :flushed_logger_mutex
|
|
76
|
+
attr_reader :flushed_logger
|
|
77
|
+
attr_reader :known_objects
|
|
78
|
+
|
|
79
|
+
def incremental_dump?(object); known_objects.include?(object) end
|
|
80
|
+
|
|
81
|
+
# call-seq:
|
|
82
|
+
# Log.log(message) { args }
|
|
83
|
+
#
|
|
84
|
+
# Logs +message+ with argument +args+. The block is called only once if
|
|
85
|
+
# there is at least one logger which listens for +message+.
|
|
86
|
+
def log(m, args = nil)
|
|
87
|
+
if m == :discovered_tasks || m == :discovered_events
|
|
88
|
+
Roby::Control.synchronize do
|
|
89
|
+
args ||= yield
|
|
90
|
+
objects = args[1].to_value_set
|
|
91
|
+
# Do not give a 'peer' argument at Distributed.format, to
|
|
92
|
+
# make sure we do a full dump
|
|
93
|
+
args = Roby::Distributed.format(args) if has_logger?(m)
|
|
94
|
+
known_objects.merge(objects)
|
|
95
|
+
end
|
|
96
|
+
elsif m == :finalized_task || m == :finalized_event
|
|
97
|
+
Roby::Control.synchronize do
|
|
98
|
+
args ||= yield
|
|
99
|
+
object = args[1]
|
|
100
|
+
args = Roby::Distributed.format(args, self) if has_logger?(m)
|
|
101
|
+
known_objects.delete(object)
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
if has_logger?(m)
|
|
106
|
+
if !args && block_given?
|
|
107
|
+
Roby::Control.synchronize do
|
|
108
|
+
args = Roby::Distributed.format(yield, self)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
logged_events << [m, Time.now, args]
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# The main logging loop. We use a separate loop to avoid having logging
|
|
117
|
+
# have too much influence on the control thread. The Log.logged_events
|
|
118
|
+
# attribute is a sized queue (of size LOGGED_EVENTS_QUEUE_SIZE) in
|
|
119
|
+
# which all the events needing logging are saved
|
|
120
|
+
def logger_loop
|
|
121
|
+
Thread.current.priority = 2
|
|
122
|
+
loop do
|
|
123
|
+
m, time, args = logged_events.pop
|
|
124
|
+
break unless m
|
|
125
|
+
|
|
126
|
+
each_logger(m) do |logger|
|
|
127
|
+
if logger.splat?
|
|
128
|
+
logger.send(m, time, *args)
|
|
129
|
+
else
|
|
130
|
+
logger.send(m, time, args)
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
if m == :flush && logged_events.empty?
|
|
135
|
+
flushed_logger_mutex.synchronize do
|
|
136
|
+
flushed_logger.broadcast
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
rescue Exception => e
|
|
142
|
+
Roby.fatal "logger thread dies with #{e.full_message}" unless e.kind_of?(Interrupt)
|
|
143
|
+
|
|
144
|
+
ensure
|
|
145
|
+
# Wake up any waiting thread
|
|
146
|
+
flushed_logger_mutex.synchronize do
|
|
147
|
+
@@logging_thread = nil
|
|
148
|
+
flushed_logger.broadcast
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# Waits for all the events queued in +logged_events+ to be processed by
|
|
153
|
+
# the logging thread. Also sends the +flush+ message to all loggers
|
|
154
|
+
# that respond to it
|
|
155
|
+
def flush
|
|
156
|
+
flushed_logger_mutex.synchronize do
|
|
157
|
+
if !logging?
|
|
158
|
+
raise "not logging"
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
logged_events.push [:flush, []]
|
|
162
|
+
flushed_logger.wait(flushed_logger_mutex)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# Requires all displays
|
|
167
|
+
def load_all_displays
|
|
168
|
+
require 'roby/log/relations'
|
|
169
|
+
require 'roby/log/execution-state'
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def open(file)
|
|
173
|
+
Logfile.open(file)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def replay(file, &block)
|
|
177
|
+
if file =~ /\.gz$/
|
|
178
|
+
require 'zlib'
|
|
179
|
+
require 'roby/log/file'
|
|
180
|
+
Zlib::GzipReader.open(file) do |io|
|
|
181
|
+
FileLogger.replay(io, &block)
|
|
182
|
+
end
|
|
183
|
+
elsif file =~ /\.db$/
|
|
184
|
+
require 'roby/log/sqlite'
|
|
185
|
+
SQLiteLogger.replay(file, &block)
|
|
186
|
+
else
|
|
187
|
+
require 'roby/log/file'
|
|
188
|
+
File.open(file) do |io|
|
|
189
|
+
FileLogger.replay(io, &block)
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
LOGGED_EVENTS_QUEUE_SIZE = 2000
|
|
196
|
+
@logged_events = SizedQueue.new(LOGGED_EVENTS_QUEUE_SIZE)
|
|
197
|
+
@flushed_logger_mutex = Mutex.new
|
|
198
|
+
@flushed_logger = ConditionVariable.new
|
|
199
|
+
@known_objects = ValueSet.new
|
|
200
|
+
|
|
201
|
+
end
|
|
202
|
+
|