roc

The ROC system allows to share objects across process, computer and programming language boundaries. The core is a network protocol using ZeroMQ which is based on the Majordomo Pattern from 7/MDP. The service identifiers are replaced by object identifier and the data part consists of JSON RPC bodies to call the object’s methods.

The core of ROC (calling other objects) has further been extended to allow asynchronous transmission of log messages and status updates.

Calling other objects

The base sytem consists of three main parts:

  • The RocServer, which takes an ordinary python object instance and shares its attributes and methods to the network.
  • The RocClient, which provides a class like interface to remote object instances.
  • The rocbroker, which organizes all the routing between servers and clients.

When a server is started, it is given an objectId which is used to locate the shared object in the network.

Usage

A simple server can be implemented for example like this:

# -*- coding: utf-8 -*-

"""
vnir (object server)
====================

This is a roc object server for VNIR camera controls.
"""
from runmacs.roc import RocStatusUpdater

OBJECT_ID = 'vnir'

if __name__ == '__main__':
    from runmacs.roc.servers import run_simple_server
    from runmacs.spec.hw.camera import VNIRCamera

    with VNIRCamera(createStatusUpdater=RocStatusUpdater) as vnir:
        run_simple_server(OBJECT_ID, vnir)

When a broker is present, the shared object vnir can be found via a RocClient:

>>> from runmacs.roc import RocClient, Endpoints
>>> ep = Endpoints('<brokerIp>')
>>> c = RocClient(ep)
>>> vnir = c['vnir'] #locate via objectId
>>> vnir.openShutter() #call a method of the (remote) shared object
>>> vnir.fps #get frames per second
10.0

Distributed Logging

Distributed logging is activated by the initRocLogging() function, which registers a log handler with the Python logging system such that standard Python log messages are delivered via the rocbroker. If the server is started as above using the runSimpleServer(), distributed logging is automatically activated.

Log messages are either displayed in a GUI, or can centrally be written to disk using the runmacs.roc.logdump.

Status Updates

The third part of ROC is the status update protocol. The status update protocol allows to send and receive any ammount of variables organized in a hierarchical tree which can be updated by any participating actor. Status updates can be sent using the RocStatusUpdater and received using the statusUpdateIterator().

More information can be found under the modules documentation:

Objects

class runmacs.roc.RocServer(brokerEndpoint, objectId, objectInstance, ctx=None)[source]

Remote Object Call server.

Parameters:
  • brokerEndpoint – network endpoint of the broker or Endpoints
  • objectId – network name of the shared object
  • objectInstance – instance of the shared (python) object
  • ctx – ZeroMQ context to use
on_request(msg)[source]

Public method called when a request arrived.

Must be overloaded!

class runmacs.roc.RocClient(broker_addr, ctx=None, timeout=2.0)[source]

Remote Object Call client.

Parameters:
  • broker_addr – network endpoint of the broker or Endpoints
  • ctx – ZeroMQ context to use
  • timeout – timeout [s] for calls

The client returns proxy objects by element access, which behave somehow like the underlying shared object. See above for further examples and explanation.

class runmacs.roc.AsyncRocClient(broker_addr, ctx=None, timeout=2.0)[source]
class runmacs.roc.Endpoints(brokerAddress, brokerBasePort=5555, transport='tcp')[source]

Manages a collection of ROC endpoints.

The purpose is to reduce the amount of configuration data (i.e. IP-Addresses) to an absolute minimum.

generalXPUB

This is for receiving log and information data.

generalXSUB

This is for dropping log and information data.

rocBroker

This is the router for plain ROC commands.

class runmacs.roc.RocLogger(nodeId, destination, ctx=None)[source]

Handles python log messages by sending them over a zmq PUB socket.

emit(record)[source]

send a record over the wire

flush()[source]

nothing to do here… (data is already sent)

class runmacs.roc.RocStatusUpdater(destination=None, ctx=None)[source]

Allows to send ROC status update messages.

emit(sensorId, data)[source]

Send a status update message.

Parameters:
  • sensorIdstr containing the dot-separated prefix of the sensor
  • datadict or list or nested of both contaning updated values

To update cpu and memory usage of the host “foo”, one might send the data as follows:

updater.emit('system.foo', {'cpu': 0.3, 'memory': 0.7})

Which should be interpreted by the receiver as a partial status three like:

{'system':
    {'foo':
        {'cpu': 0.3, 'memory': 0.7}
    }
}
runmacs.roc.statusUpdateIterator(source, mask='', ctx=None, timeout=None)[source]

Iterator over received status updates.

Parameters:
  • source – Source address or Endpoints instance of the broker.
  • mask – Prefix of the subtree of updates of interest (e.g. ‘system’ or ‘system.foo’), can be a list
  • ctx – ZeroMQ Context to use
  • timeout – Timeout after which an empty status is yielded in any case.

Printing all updates can be done like:

for msg in statusUpdateIterator(ep):
    print msg