Troubleshooting

See also

Support
If this page doesn’t help

Spread Does not Work

Problem (applies to C++, Python)

Communication over Spread does not work anymore. Spread settings are ignored.

Solution

  1. Spread plugin (applies to C++)

    See also

    Plugins

    Specification of RSB plugins

    Starting with version 0.9, the C++ implementation does no longer include the Spread-based transport in the RSB core. Instead, the transport is available as a plugin which has to be loaded explicitly. This can, for example, be done by including the following fragment in one of the RSB configuration files PREFIX/etc/rsb.conf, ~/.config/rsb.conf or $(pwd)/rsb.conf:

    [plugins.cpp]
    load = rsbspread
    
  2. Configuration

    Starting with version 0.7, RSB uses a transport that implements a custom TPC-based protocol to facilitate the easy use of the framework without dependencies on 3rd party libraries. In order to restore the previous behavior of using the Spread transport, the configuration needs to be changed.

    This can be changed in three ways:

    1. Globally for all RSB programs (or running under a particular UNIX user)

      Create or modify a RSB configuration file PREFIX/etc/rsb.conf or ~/.config/rsb.conf to contain the following lines:

      1
      2
      3
      4
      [transport.spread]
      enabled = 1
      [transport.socket]
      enabled = 0
      

      Lines 3 and 4 can be omitted to enable both transports in parallel.

      Note

      On windows it might be necessary to also set host = localhost and port = 4803 explicitly in the Spread transport section.

    2. Locally for the current directory

      Create a RSB configuration file $(pwd)/rsb.conf with the same contents as described above.

    3. For the current shell

      Set and export RSB_TRANSPORT_SPREAD_ENABLED and RSB_TRANSPORT_SOCKET_ENABLED environment variables as follows:

      $ export RSB_TRANSPORT_SPREAD_ENABLED=1
      $ export RSB_TRANSPORT_SOCKET_ENABLED=0
      

Configuring the TCP-based Transport

Problem (applies to C++,Common Lisp,Python)

How can I configure the TCP-based transport?

Solution

The TCP-based transport can be configured locally or globally by placing the following content in PREFIX/etc/rsb.conf, ~/.config/rsb.conf or $(pwd)/rsb.conf:

[transport.socket]
enabled = 1
host    = HOSTNAME
port    = 4444
server  = auto

HOSTNAME can be localhost (if all processes are going to run on the same node), a hostname or an IP address.

Note

The above configuration uses server = auto which causes the initial RSB process to create the specified server and subsequent processes to connect to that server, see RSB_TRANSPORT_SOCKET_SERVER.

Linker Errors at Runtime

Problem (applies to C++)

I compiled and installed successfully, but RSB binaries/libraries produce linker errors at runtime.

Solution

The C++ implementation of RSB is built without fixed rpath by default. As a result, installed RSB binaries and libraries do not contain information regarding the location of their dependencies. This potentially causes runtime linking to fail because the dependencies cannot be located.

There are two possible solutions:

  1. Building and installing RSB with fixed rpath

    This can be achieved by configuring RSB with

    $ cmake -DCMAKE_INSTALL_RPATH_USE_LINK_PATH=TRUE
    

    This instructs CMake to set the rpath of installed libraries and executables to the values used for building them. Normally the rpath is stripped at installation time.

  2. Use of the LD_LIBRARY_PATH environment variable

    When the value of LD_LIBRARY_PATH contains the directory/directories into which RSB (and its dependencies) have been installed, these dependencies can be located at runtime. LD_LIBRARY_PATH can be set, for example, like this:

    $ export LD_LIBRARY_PATH=PREFIX/lib
    

    where PREFIX is the prefix directory into which RSB and its dependencies have been installed.

    Warning

    This workaround is not permanent and has to be repeated for each new shell that should be able to execute RSB binaries or RSB-based programs.

Spread Warning in Tools

Problem (applies to Common Lisp)

When I start any of the Tools, the following happens:

$ logger socket://localhost:7777
WARNING:
  Failed to load Spread library: Unable to load any of the alternatives:
  ("libspread-without-signal-blocking.so" "libspread.so" "libspread.so.2"
   "libspread.so.2.0" "libspread.so.1").
  Did you set LD_LIBRARY_PATH?
  Spread transport will now be disabled.
[execution continues, but Spread transport does not work]

Solution

Place one of the mentioned Spread libraries (typically libspread.so.2.0) on the system library search path or set LD_LIBRARY_PATH appropriately.

Missing Converters

See also

Registering Converters
Registering additional converters

Problem (applies to all implementations)

When a listener in my component receives certain events, it crashes and complains about missing converters. For example like this:

$ ./myconponent
[...]
terminate called after throwing an instance of 'rsc::runtime::NoSuchObject'
  what():  No converter for wire-schema or data-type `.rst.vision.Image'.
Available converters: {
  bool: *rsb::converter::BoolConverter[wireType = std::string, wireSchema = bool, dataType = bool] at 0x9d0b80
  [...]
}

Solution

There can be several solutions to this problem.

  1. The listener could receive unexpected events. This can be diagnosed using the logger. If the listener does indeed receive unexpected events, the problem can be fixed by letting the offending informer or the listener itself operate on a different scope.
  2. The converter configuration could be wrong. If the listener only receives expected events, it may be missing a suitable converter. This problem can be solved by registering a suitable converter. Registering a converter may be achieved by loading a plugin.
  3. The converter registration could happen after the listener has already been created. In that case, the listener would use the “old” set of converters.

Polymorphic Informers

Problem (applies to C++)

I thought it is possible, to send different data types through the same informer. However, I get this error (also using rsb::InformerBase)

terminate called after throwing an instance of 'std::invalid_argument'
what(): Specified event type PAYLOAD-TYPE does not match informer type INFORMER-TYPE.
Aborted (core dumped)

Note

In the actual error message, PAYLOAD-TYPE and INFORMER-TYPE would be the data type of the payload attempted to send and the specified data type of the informer respectively.

Solution

This can be achieved by specifying the pseudo-type rsb::AnyType as the data type of the created informer:

1
2
3
4
5
6
7
8
9
    // create an informer that is capable of sending events containing any kind
    // of data on the scope "/example/informer".
    Informer<AnyType>::Ptr informer = factory.createInformer<AnyType> (
            Scope("/example/informer"));

    // create data to send over the informer. Data is always maintained in
    // shared_ptr instances. Here we use typed informer to create a shared_ptr
    // of the data type we want to send
    Informer<string>::DataPtr s(new string("blub"));

Note

In all other RSB implementations, this kind of informer can be created by specifying a builtin supertype such as Object (Java), object (Python) or t (Common Lisp) as the data type of the informer.

Multiple Arguments in RPC Calls

See also

Remote Procedure Calls
Examples about using remote procedure calls
Request-Reply Communication
Specification of remote procedure calls

Problem (applies to all implementations)

I would like to call an RPC method with two payloads. RSB seems to only support a single argument in RPC calls, so what is the most elegant way to do this?

Solution

Currently, RSB only supports a single payload for each event. Since RPC calls are implemented in terms of events, the same limitation applies. As a consequence, multiple arguments for a method call have to be collected into a single payload.

Assuming Google Protocol Buffers are used and the method in question should have the signature add(ComplexNumber, ComplexNumber), a definition like the following could be used:

message AdditionRequest {

    required ComplexNumber x = 1;
    required ComplexNumber y = 2;

}

For Python, the code implementing this method would then be

def add(request):
  result = ComplexNumber()
  result.real = request.x.real + request.y.real
  result.imag = request.x.imag + request.y.imag
  return result
server.addMethod('add', add)

A Message about no Handlers being found appears

Problem (applies to Python)

When I import the rst or rstsandbox module, a message like:

No handlers could be found for logger "rstsandbox"

appears. Am I doing something wrong?

Solution

Everything is fine. The output is produced by Python’s logging module when logging has not been configured. RSB uses this module to log messages.

If you find these messages annoying, add the following code fragment to your program:

import logging
logging.basicConfig(level = logging.WARNING)

See logging.basicConfig() for more configuration options.

Java programs using the TCP-transport do not communicate with other languages

Problem (applies to Java)

Events from a Java process using the TCP-transport are not received by other languages or vice versa.

Solution

The Java runtime sometime prefers to bind against IPv6 addresses even if IPv4 addresses are specified. This seems to be an internal behavior of the Java runtime. Other implementations use IPv4 as the default. As a consequence, Java operates on IPv6 and the other languages on IPv4 and no connection exists. To force Java to use IPv4, specify the following JVM property for your Java applications:

-Djava.net.preferIPv4Stack=true

I cannot make the Socket Transport with “auto” Mode work across multiple Machines

Problem (applies to all implementations)

I want to connect processes on two or more machines and use the “auto” mode of the socket transport with a configuration like this:

[transport.socket]
hostname = SOMEHOST
server = auto

where SOMEHOST is the name of one of the hosts or localhost. If I start my processes in a particular order, communication sometimes works, but generally I only get failed connection attempts.

Solution

The “auto” mode of the socket transport is intended to be used with simple setups confined to a single computer. It can be used to make such setups “just work”. For other setups, it is only usable with severe restrictions and should probably be avoided.

If you want to connect processes across multiple machines:

  • Consider switching to the Spread transport if you want to connect very many processes or restart all processes arbitrarily.

  • If you want to use the socket transport

    1. Determine one particular process that should always act as the server. This can also be an additional process like the Logger. Note that this choice can impact the performance of your setup very much.

    2. Configure all other processes to act as clients, for example with this configuration snippet

      [transport.socket]
      hostname = THE-SERVER-HOST
      server = 0
      
    3. You can add client processes or restart them arbitrarily and also share the above configuration among all client processes.

How many Spread Daemons do I need?

Problem (applies to all implementations)

I want to have multiple processes communicate using the Spread transport. Do I need this Spread daemon and if so, how many instances do I have to start and on which machines? I heard that running multiple Spread daemons can even cause severe network problems.

Solution

First of all, Spread daemons really can cause severe network problems when configured incorrectly. We therefore recommend to always start with a single Spread daemon using the default configuration unless a different setup is absolutely necessary. Beyond this simple advice, unfortunately, there are several different possibilities for setting up one or more Spread daemons. In any case, you always need at least one Spread daemon.

If all processes run on a single machine, you can start a single Spread daemon using the default configuration like this:

$ SPREAD_INSTALL_PREFIX/sbin/spread -n localhost

This is a simple and safe configuration and should already cover many simple setups.

If multiple computers are involved, a single Spread daemon with the above configuration may still be sufficient since it can be contacted by clients on remote hosts (see RSB_TRANSPORT_SPREAD_HOST). However, this configuration may not achieve the best performance the Spread framework is capable of. If you need better performance and thus more sophisticated configurations, consult the Spread documentation or write to the RSB mailing list.