<previous | top | next> Pyro Manual

6. Pyro's Implementation

The purpose of this chapter is to provide some insight in the Pyro's implementation. However please keep in mind that it is quite tedious for me to update this chapter with each Pyro release, so I want to stress the fact that the source code is probably the best place to look if you want to find out specific details about Pyro's implementation.

Nevertheless this chapter is a nice starting point to explore the different parts that make up Pyro.

XXX Unfinished

The command-line tools (bin/*)

The command-line tools are all in fact very small Python scripts. They contain a few Python statements that start the actual tools, which are part of the Pyro package:

Tool Implemented in Notes
nsc Pyro.nsc  
xnsc Pyro.xnsc  
pyroc Pyro.pyroc  
genguid Pyro.util entrypoint is genguid_scripthelper(). Module contains other things as well.
ns Pyro.naming entrypoint is main(). Module contains other things as well.

Pyro package initializer (Pyro/__init__.py)

Pyro is a Python package and as such is contained in the 'Pyro' directory. This directory contains the different module files that make up the Pyro system. One of them is the initialization file, __init__.py. It sets Pyro.PYRO_VERSION to the actual Pyro version, for instance '1.4'. It also loads the configuration settings for Pyro (Pyro.config.* items).

Configuration (Pyro/configuration.py)

This module contains the logic that deals with Pyro's configuration. There is a Config class and a ConfigReader class. The Config class is the container for all configuration items. The instance is available as Pyro.config (created in the package initializer, see above). The configuration items are all attributes of this object. Config uses the ConfigReader to read Pyro's configuration file. It deals with defaults and environment settings too.

Core library (Pyro/core.py)

This module contains all core logic of Pyro that is not tied to the network protocol that is used. This means that you will not find any TCP/IP socket specific code in the core module; the protocol module contains this. What the core module does contain is all stuff that realize the core functions of Pyro:

ObjBase
Server-side object implementation base class or master class with the actual object as delegate. It supplies the methods for remote method invocation (Pyro_dyncall) and remote attribute access (remote_getattr etc.)
PyroURI
Pyro Universal Resource Identifier. This class represents a Pyro URI (which consists of four parts: a protocol identifier, an IP address, a portnumber, and an object ID). PyroURI can be converted to and from a - human readable - string.
DynamicProxy and DynamicProxyWithAttrs
These two classes are the dynamic Pyro proxies. They can be used by clients to invoke objects for which they have no precompiled proxy. The "WithAttrs" proxy is needed if you want to do direct attribute access on remote Pyro objects. The proxies have a special __invokePYRO__ method that intercepts method calls to pass them via the protocol adapter to the remote Pyro object. Special care is taken to make proxy objects suitable for pickling so they can be transported trough the Pyro protocol across the network.
getProxyForURI and getAttrProxyForURI
Helper functions to create proxies directly from a given Pyro URI (object).
Daemon
The server-side Pyro daemon. Accepts and dispatches incoming Pyro method calls. It is derived from the low level TCPServer and contains the server end of a protocol adapter. The daemon passes incoming method calls (via its handleRequest method) to the protocol adapter that sorts out what to do exactly. The connect and disconnect methods are used to keep track of server side Pyro objects. The Daemon's handleError is used in case of a Pyro error, it processes the error and cleans things up.
Pyro client and Pyro server initialization code
The initClient and initServer functions currently only write some friendly strings to the log. However in the future they might be needed to do more complex initialization.

Naming Service (Pyro/naming.py)

This module contains all logic that deals with object naming and locations. Pyro's Name Server is implemented here as well as various other things:

XXXXXXX

Protocol Adapters (Pyro/protocol.py)

The idea behind this module is to make it fairly straightforward to switch the underlying protocol that Pyro uses. Currently only one implementation is available: the native PYRO protocol that sits on top of TCP/IP.

XXXXXXX

Utilities (Pyro/util.py)

This module defines various utility functions and classes:

pickle
Is the most efficient pickle module available (cPickle or the regular pickle module)
LoggerBase
This is the abstract base class of the various logging classes, see the next two items. Don't use this directly.
SystemLogger
An object of this class is directly available as Pyro.util.Log and this is Pyro's system logger that writes to Pyro's system logfile.
UserLogger
An object of this class can be constructed to create a user logger that writes to the user logfile.
ArgParser
A simple command line argument parser like the getopt function in ANSI C. Pyro's command line tools use this. It can parse command line options according to an option specification string. The getOpt member is used to read the results.
int2binstr
Converts an integer to a binary string representation with a specified byte length.
binstr2int
Converts a binary string to an integer (the reverse of int2binstr).
getBinaryGUID
Generates a new binary GUID. This is essentially a big number that is unique in time and in space. Unique in time means that every moment you generate a new GUID it is different from the ones you generated before. Pyro does this by using a time stamp as part of the GUID. Unique in space means that when you generate a GUID on a different machine, it will be different from the GUID you generated elsewhere (even when you generate them exactly the same moment). Pyro does this by using the network address of your computer as part of the GUID. The GUID is constructed as follows: AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC (a 128-bit number in hex) where A=network address, B=timestamp, C=random. The 128-bit number is returned as a string of 16 8-bits characters.
bin2ascGUID
Converts a binary GUID to a readable string: "AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC".
asc2binGUID
Converts a string GUID to a binary one (16-byte string).
genguid_scripthelper
This helper function is used by the genguid command line utility, which prints a new GUID.
supports_multithreading
Pyro uses this to determine if your Python implementation supports multithreading. If it does, Pyro defaults to multithreaded server support.

Exception definitions (Pyro/errors.py)

This module defines Pyro.PyroError and its derived exceptions. PyroError is the Pyro exception type that is used for problems within Pyro. User code should not use it! Also, this module defines the PyroExceptionCapsule class, which is used to represent any Python exception that has to be transported across the network, and raised on the other side (by invoking raiseEx on this object).