Basic Concept and Environment

Overview

The basic idea is to have an application which runs several Services in separate threads or processes. The communication is done using Pyro4. The process and thread creation is provided by multiprocessing respectively multiprocessing.dummy.

_images/single_application.png

The prerequisite is to run a NameServer, which manages the connection infos for all services, and a LogServer to manage logging across process boundaries.

It is possible to access the services across application boundaries as long as one application runs the NameServer and LogServer.

_images/overview.png

Warning

It is not possible to run more than one NameServer or LogServer

NameServer

Each Service is registered at the NameServer. The name which is used for registering is the return value of Service.get_pyro_name(). By default this is the class name converted to upper. Therefore it is not possible to run 2 services of the same class. If this is required, derive a class with a different name. Another possibility would be to overwrite Service.get_pyro_name().

Note

It is possible to disable() the NameServer, e.g. to force create_logger to use a local logger, when running a simple script concurrent to a service-based application. (See Local Service Example)

Hint

If you want to connect to a service, but not import it, you can define a class with the same name and no functionality, which is derived of Service, and you are able to connect to the service.

Logging

The PyroMP package has a module to provide logging supporting the multiprocessing feature. The basic idea is to have one Service named LogServer which manages several logging.Logger. The PyroMP logger acts like the built-in one but forwards everything to the logger with the same name at the LogServer.

Usually it is used with a concurrent LogServer:

from PyroMP import NameServer
import PyroMP.log_server as log
with NameServer():
    with log.LogServer():
        log.set_loglevel(log.INFO)
        logger = log.create_logger("ExampleLogger")
        logger.info("Example message")

Log:

2014-02-19 14:42:48,473 - LogServer.ExampleLogger        - INFO     - Example message

but it can also be used locally:

from PyroMP import NameServer
import PyroMP.log_server as log
# disable NameServer to avoid unexpected behavior
# in case that another NameServer is running concurrently
NameServer.disable()
log.set_loglevel(log.INFO)
logger = log.create_logger("ExampleLogger")
logger.info("Example message")

Log:

2014-02-19 14:42:50,572 - LogServer.ExampleLogger        - INFO     - Example message

As you can see, PyroMP.log_server module exports the log levels as exported by logging (see Python Documentation):

  • INFO
  • DEBUG
  • WARNING
  • ERROR
  • CRITICAL
  • FATAL
  • NOTSET

The same is applied for logging.Formatter which is available using PyroMP.log_server.Formatter

API Reference

class PyroMP.NameServer

Manages a thread which runs a Pyro4.naming.NameServer

Further information

Class Methods

classmethod enable()

Enables the NameServer functionality

classmethod disable()

Disables the NameServer functionality

If disabled, locate() will always raise an error and start() won’t do anything.

classmethod locate()

Works like locateNS(), but supports enabling and disabling.

Raises :

exc : NameServerError

If no NameServer is found

classmethod start()

If there is no Pyro4.naming.NameServer running, a thread is started that runs one

classmethod stop()

Stops the name server, if started in this process


PyroMP.log_server.create_logger(name)

Factory function, that returns a proxy for a logging.Logger.

If a LogServer is running, it is used. Else a local logging.Logger is used.

The returned object supports all functions that are provided by logging.Logger

Methods of the returned object

Logger.add_filehandler(filename, formatter=None, level=None)

Adds a logging.FileHandler for the file with the given filename. If formatter is provided the given logging.Formatter is used. If level is provided it is forwarded to setLevel().

Logger.add_streamhandler(stream=None, formatter=None)

Adds a logging.StreamHandler to which stream argument is forwarded. If formatter is provided the given logging.Formatter is used. If level is provided it is forwarded to setLevel().


PyroMP.log_server.get_server_root_logger()
Returns :

root_logger : LoggerProxy

Logger proxy to the root logger of the current LogServer


class PyroMP.log_server.LogServer

Bases: Service

Service that manages the logging stuff, started in a thread.

Class Methods

classmethod is_running()

Returns True if a LogServer is available otherwise False


PyroMP.log_server.set_loglevel(level)

Set the level to level for all existing loggers.

Parameters :

level : int

Desired level

Table Of Contents

Previous topic

Quickstart and Tutorial

Next topic

Basic Services

This Page