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.
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.
Warning
It is not possible to run more than one NameServer or LogServer
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.
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):
The same is applied for logging.Formatter which is available using PyroMP.log_server.Formatter
Manages a thread which runs a Pyro4.naming.NameServer
Class Methods
Enables the NameServer functionality
Disables the NameServer functionality
If disabled, locate() will always raise an error and start() won’t do anything.
Works like locateNS(), but supports enabling and disabling.
Raises : | exc : NameServerError
|
---|
If there is no Pyro4.naming.NameServer running, a thread is started that runs one
Stops the name server, if started in this process
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
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().
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().
Returns : | root_logger : LoggerProxy
|
---|
Bases: Service
Service that manages the logging stuff, started in a thread.
Class Methods
Returns True if a LogServer is available otherwise False
Set the level to level for all existing loggers.
Parameters : | level : int
|
---|
See also