Class: Syskit::RobyApp::UnmanagedProcess
- Extended by:
- Logger::Hierarchy
- Includes:
- Logger::Hierarchy
- Defined in:
- lib/syskit/roby_app/unmanaged_process.rb
Overview
A class API-compatible with Orocos::Process that represents tasks that are not started by the Syskit instance
An UnmanagedProcess can basically be in three states, which are reflected by three threads
#monitor_thread is started when all tasks have been resolved in #resolve_all_tasks. It verifies that the tasks are still reachable. The thread returns when it is not the case.
Whether the process is stil in a good state or not should be tested with #dead?. #verify_threads_state verifies that the threads themselves did not terminate with an exception (and throw the exception).
Defined Under Namespace
Classes: TerminateThread
Instance Attribute Summary collapse
-
#deployed_tasks ⇒ {String=>TaskContext}
readonly
The set of deployed tasks.
-
#host_id ⇒ String
readonly
The host on which this process' tasks run.
-
#monitor_thread ⇒ Object
readonly
private
The thread that monitors the tasks availability.
-
#name_service ⇒ Object
readonly
The name service object which should be used to resolve the tasks.
-
#pid ⇒ Integer
readonly
The PID of the process in which the tasks run.
-
#process_manager ⇒ #dead_deployment?
readonly
The UnmanagedTasksManager object which created this.
Instance Method Summary collapse
-
#alive? ⇒ Boolean
True if the process is running.
-
#dead? ⇒ Boolean
Returns true if the process died.
-
#initialize(process_manager, name, model, host_id: 'unmanaged_process') ⇒ UnmanagedProcess
constructor
Creates a new object managing the tasks that represent a single unmanaged process.
- #join ⇒ Object
-
#kill(wait = false) ⇒ Object
“Kill” this process.
-
#monitor(period: 0.1) ⇒ Object
private
Implementation of the monitor thread, i.e.
-
#on_localhost? ⇒ Boolean
Whether the tasks in this process are running on the same machine than the ruby process.
-
#quitting? ⇒ Boolean
Whether #kill requested for #monitor_thread to quit.
-
#ready? ⇒ Boolean
Returns true if the tasks have been successfully discovered.
- #resolve_all_tasks(cache = Hash.new) ⇒ Object
-
#running? ⇒ Boolean
True if the process is running.
-
#spawn(options = Hash.new) ⇒ void
“Starts” this process.
-
#task(task_name) ⇒ Object
Returns the component object for the given name.
-
#terminate_and_join_thread(thread) ⇒ Object
private
Helper method to kill a thread.
-
#verify_threads_state ⇒ Object
Verifies that the monitor thread is alive and well, or that the process either terminated or is not spawned yet.
Constructor Details
#initialize(process_manager, name, model, host_id: 'unmanaged_process') ⇒ UnmanagedProcess
Creates a new object managing the tasks that represent a single unmanaged process
78 79 80 81 82 83 84 85 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 78 def initialize(process_manager, name, model, host_id: 'unmanaged_process') @process_manager = process_manager @deployed_tasks = nil @name_service = process_manager.name_service @host_id = host_id @quitting = Concurrent::Event.new super(name, model) end |
Instance Attribute Details
#deployed_tasks ⇒ {String=>TaskContext} (readonly)
The set of deployed tasks
35 36 37 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 35 def deployed_tasks @deployed_tasks end |
#host_id ⇒ String (readonly)
The host on which this process' tasks run
40 41 42 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 40 def host_id @host_id end |
#monitor_thread ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
The thread that monitors the tasks availability
It is spawned the first time #wait_running returns true
67 68 69 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 67 def monitor_thread @monitor_thread end |
#name_service ⇒ Object (readonly)
The name service object which should be used to resolve the tasks
60 61 62 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 60 def name_service @name_service end |
#pid ⇒ Integer (readonly)
The PID of the process in which the tasks run
This is always Process.pid as ruby tasks are instanciated inside the ruby process
57 58 59 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 57 def pid @pid end |
#process_manager ⇒ #dead_deployment? (readonly)
The Syskit::RobyApp::UnmanagedTasksManager object which created this
If non-nil, the object's #dead_deployment will be called when self is stopped
29 30 31 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 29 def process_manager @process_manager end |
Instance Method Details
#alive? ⇒ Boolean
True if the process is running. This is an alias for running?
197 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 197 def alive?; !dead? end |
#dead? ⇒ Boolean
Returns true if the process died
187 188 189 190 191 192 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 187 def dead? if monitor_thread return !monitor_thread.alive? else quitting? end end |
#join ⇒ Object
201 202 203 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 201 def join raise NotImplementedError, "UnmanagedProcess#join is not implemented" end |
#kill(wait = false) ⇒ Object
“Kill” this process
It shuts down the tasks that are part of it
157 158 159 160 161 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 157 def kill(wait = false) # Announce we're quitting to #monitor_thread. It's used in # #dead? directly if there is no monitoring thread @quitting.set end |
#monitor(period: 0.1) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Implementation of the monitor thread, i.e. the thread that will detect if the deployment disappears
169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 169 def monitor(period: 0.1) while !quitting? deployed_tasks.each_value do |task| begin task.ping rescue Orocos::ComError return end end sleep period end end |
#on_localhost? ⇒ Boolean
Whether the tasks in this process are running on the same machine than the ruby process
This is always true as ruby tasks are instanciated inside the ruby process
49 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 49 def on_localhost?; host_id == 'localhost' end |
#quitting? ⇒ Boolean
Whether #kill requested for #monitor_thread to quit
182 183 184 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 182 def quitting? @quitting.set? end |
#ready? ⇒ Boolean
Returns true if the tasks have been successfully discovered
195 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 195 def ready?; !!deployed_tasks end |
#resolve_all_tasks(cache = Hash.new) ⇒ Object
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 110 def resolve_all_tasks(cache = Hash.new) resolved = model.task_activities.map do |t| [t.name, (cache[t.name] ||= name_service.get(t.name))] end @deployed_tasks = Hash[resolved] @monitor_thread = Thread.new do monitor end return @deployed_tasks rescue Orocos::NotFound, Orocos::ComError => e if Time.now - @last_warning > 5 Syskit.warn "waiting for unmanaged task: #{e}" @last_warning = Time.now end nil end |
#running? ⇒ Boolean
True if the process is running. This is an alias for alive?
199 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 199 def running?; alive? end |
#spawn(options = Hash.new) ⇒ void
This method returns an undefined value.
“Starts” this process
It spawns a thread that returns once the task got resolved
92 93 94 95 96 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 92 def spawn( = Hash.new) @spawn_start = Time.now @last_warning = Time.now @deployed_tasks = nil end |
#task(task_name) ⇒ Object
Returns the component object for the given name
132 133 134 135 136 137 138 139 140 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 132 def task(task_name) if !deployed_tasks raise RuntimeError, "process not running yet" elsif task = deployed_tasks[task_name] task else raise ArgumentError, "#{task_name} is not a task of #{self}" end end |
#terminate_and_join_thread(thread) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Helper method to kill a thread
145 146 147 148 149 150 151 152 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 145 def terminate_and_join_thread(thread) return if !thread.alive? thread.raise TerminateThread begin thread.join rescue TerminateThread end end |
#verify_threads_state ⇒ Object
Verifies that the monitor thread is alive and well, or that the process either terminated or is not spawned yet
If the monitor thread terminated unexpectedly, it will raise the exception that terminated it, or a RuntimeError if no exceptions have been raised (which should not be possible)
104 105 106 107 108 |
# File 'lib/syskit/roby_app/unmanaged_process.rb', line 104 def verify_threads_state if monitor_thread && !monitor_thread.alive? monitor_thread.join end end |