module Orocos::Async
Module for asynchronously accessing OROCOS Tasks by deferring blocking calls to the thread pool {Orocos::Async.thread_pool}. The results of the calls are later on processed by the event loop {Orocos::Async.event_loop} to synchronize them with the main thread. Therefore to use the asynchronous API the event loop must be running by either calling {Async.exec} or {Async.step}.
All ruby OROCOS objects are wrapped by asynchronous counter parts:
Orocos::NameService => Orocos::Async::NameService Orocos::TaskContext => Orocos::Async::TaskContext Orocos::OutputPort => Orocos::Async::OutputPort
These wrappers can be created without the need for a running remote Orocos Task:
task = Orocos::Async.name_service.get "task_name" port = task.port "port_name" reader = port.reader
The asynchronous object usually forwards all calls to its synchronous counter part. But if a code block is given the block is used as callback and the original call is deferred to a thread pool:
# synchronous blocking calls puts task.state puts reader.read # asynchronous non blocking calls task.state do |state| puts state end reader.read do |value| puts value end
If a method call needs the remote Orocos Task which is currently not reachable the method call will be suppressed and nil is returned. This behaviour can be changed by setting [TaskContext#raise=] to true.
Most of the asynchronous object have a way to register callbacks for certain events. Most of these events are generated by polling but when ever it is possible they are generated by blocking function calls, called from a worker thread. Therefore if too many events are monitored the thread pool might run short on worker threads.
# these events are generated by polling task.on_connect do puts "connected" end task.on_disconnect do puts "disconnected" end task.on_reconnect do puts "reconnected" end # this will block a worker thread until # the state changed task.on_state_change do |state| puts state end # this will block a worker thread until # new data are available port.on_new_data do |data| puts data end
The polling frequency can be changed by setting the period attribute of each asynchronous object.
Constants
- KNOWN_ERRORS
Public Class Methods
# File lib/orocos/async/async.rb, line 88 def self.clear event_loop.clear @name_service = nil end
Returns the event loop used by {Orocos::Async}
@return [Utilrb::EventLoop] The event loop
# File lib/orocos/async/async.rb, line 96 def self.event_loop unless @event_loop @event_loop = Utilrb::EventLoop.new @event_loop.thread_pool.resize(5,20) end @event_loop end
(see NameService#get)
# File lib/orocos/async/name_service.rb, line 16 def self.get(name,options =Hash.new) name_service.get(name,options) end
Returns the global async name service abstracting all underlying name services. This should be the default way to acquire an handle to an Orocos Task by its name. If the IOR of the task is already known {Async::TaskContext} should directly be used.
# File lib/orocos/async/name_service.rb, line 7 def self.name_service @name_service ||= Orocos::Async::NameService.new() end
# File lib/orocos/async/name_service.rb, line 11 def self.name_service=(name_service) @name_service = nil end
# File lib/orocos/async/name_service.rb, line 20 def self.proxy(name,options = Hash.new) name_service.proxy(name,options) end
Returns the thread loop used by {Orocos::Async}. It is the same than the one used by {Orocos::Async.event_loop}
@return [Utilrb::ThreadPool] The event loop
# File lib/orocos/async/async.rb, line 108 def self.thread_pool event_loop.thread_pool end