Module: Orocos::Async

Extended by:
Forwardable
Defined in:
lib/orocos/async/async.rb,
lib/orocos/ros/async.rb,
lib/orocos/async/object_base.rb,
lib/orocos/async/name_service.rb,
lib/orocos/async/log/task_context.rb,
lib/orocos/async/task_context_base.rb,
lib/orocos/async/task_context_proxy.rb

Overview

Module for asynchronously accessing OROCOS Tasks by deferring blocking calls to the thread pool Async.thread_pool. The results of the calls are later on processed by the event loop 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.

Defined Under Namespace

Modules: CORBA, Local, Log, ROS Classes: AttributeBaseProxy, AttributeProxy, DelegatorDummy, EventListener, NameService, NameServiceBase, ObjectBase, PortProxy, PropertyProxy, RemoteNameService, SubPortProxy, TaskContextBase, TaskContextProxy

Constant Summary collapse

KNOWN_ERRORS =
[Orocos::ComError,Orocos::NotFound,Typelib::NotFound,Orocos::TypekitTypeNotFound,Orocos::TypekitTypeNotExported,Orocos::StateTransitionFailed,Orocos::ConnectionFailed,OroGen::DefinitionTypekitNotFound]

Class Method Summary collapse

Class Method Details

.clearObject



88
89
90
91
# File 'lib/orocos/async/async.rb', line 88

def self.clear
    event_loop.clear
    @name_service = nil
end

.event_loopUtilrb::EventLoop

Returns the event loop used by Orocos::Async

Returns:

  • (Utilrb::EventLoop)

    The event loop



96
97
98
99
100
101
102
# 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

.exec(period = 0.05, &block) ⇒ Object



85
# File 'lib/orocos/async/async.rb', line 85

def_delegators :event_loop,:exec,:wait_for,:step,:steps,:stop,:every,:once

.get(name, options = Hash.new) ⇒ Orocos::TaskContext, Orocos::Log::TaskContext

Gets an handle to a local/remote Orocos Task having the given name.

Parameters:

  • name (String)

    the name of the TaskContext

  • options (Hash) (defaults to: Hash.new)

    the options used by the name service to find the TaskContext

Options Hash (options):

  • :name (String)

    Overwrites The real name of the task

  • :process (Orocos::Process)

    The process supporting the task

Returns:

Raises:

See Also:



16
17
18
# File 'lib/orocos/async/name_service.rb', line 16

def self.get(name,options =Hash.new)
    name_service.get(name,options)
end

.name_serviceObject

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.



7
8
9
# File 'lib/orocos/async/name_service.rb', line 7

def self.name_service
    @name_service ||= Orocos::Async::NameService.new()
end

.name_service=(name_service) ⇒ Object



11
12
13
# File 'lib/orocos/async/name_service.rb', line 11

def self.name_service=(name_service)
    @name_service = nil
end

.proxy(name, options = Hash.new) ⇒ Object



20
21
22
# File 'lib/orocos/async/name_service.rb', line 20

def self.proxy(name,options = Hash.new)
    name_service.proxy(name,options)
end

.step(time = Time.now, &block) ⇒ Object



85
# File 'lib/orocos/async/async.rb', line 85

def_delegators :event_loop,:exec,:wait_for,:step,:steps,:stop,:every,:once

.thread_poolUtilrb::ThreadPool

Returns the thread loop used by Orocos::Async. It is the same than the one used by event_loop

Returns:

  • (Utilrb::ThreadPool)

    The event loop



108
109
110
# File 'lib/orocos/async/async.rb', line 108

def self.thread_pool
    event_loop.thread_pool
end

.wait_for(&block) ⇒ Object



85
# File 'lib/orocos/async/async.rb', line 85

def_delegators :event_loop,:exec,:wait_for,:step,:steps,:stop,:every,:once