| <previous | contents | next> | Pyro Manual | 
Nevertheless this chapter is a nice starting point to explore the different parts that make up Pyro.
bin/* - Command-line tools 
  __init__.py - Pyro package initialization 
  configuration.py - Configuration code 
  constants.py - Global constants used troughout Pyro
  core.py - Core code 
  naming.py - Name Server 
  protocol.py - Protocol adapters 
  util.py - Utility code 
  errors.py - Exception definitions 
  Pyro.EventService - Event Server package
  Pyro.ext - Extensions package
  
Your code doesn't call a Pyro object directly. It calls a method on a proxy that acts just
like the Pyro object it represents. The proxy intercepts the method call by using a special
implementation of __getattr__, that passes the call to __invokePYRO__.
In turn, that method forwards the call to the protocol adapter, that creates a message
containing all the details of the call (using pickle to marshall all Python
objects). The message is passed via the network to the Pyro daemon on the other side.
The daemon receives the message and unmarshalls the request. It now knows the objectID
of the required Pyro objects, the desired member function to call, and its arguments.
It looks up the Pyro Object in its table and calls the Pyro_dyncall method.
This method is in ObjBase which is the base class of all Pyro objects.
This method uses the appropriate apply call on itself to call the actual
method. The result of the method is handed back to the Pyro daemon, that marshalls
it, and passes it back over the network to the calling protocol adapter. The adapter
on the client side unmarshalls the result data, hands it back to the proxy that called it,
and then the __invokePYRO__ method of the proxy returns the result data
as if it was obtained using a regular method call on a local object!
This was Pyro in a nutshell. There are many more things to consider, such as transporting modules (mobile objects or even mobile agents) and oneway calls, but you have to read the source anyway to find all the gory details.
| Tool | Implemented in | Notes | 
|---|---|---|
| es | Pyro.EventService.Server | start Event Server | 
| nsc | Pyro.nsc | control Name Server | 
| xnsc | Pyro.xnsc | Tkinter-GUI version of nsc | 
| wxnsc | Pyro.wxnsc | WxPython/WxWindows version of nsc, with nice tree view of namespace | 
| pyroc | Pyro.pyroc | Creates static proxies (.py source files) for pyro objects - hardly needed anymore | 
| genguid | Pyro.util | create a GUID, entrypoint is genguid_scripthelper() | 
| ns / rns | Pyro.naming | start Name Server, entrypoint is main() | 
| nsd / esd | Pyro.ext.daemonizer | Unix initd daemon scripts for name server and event server | 
| nssvc / essvc | Pyro.ext.NS_NtService and ES_NTService | Windows NT Service control scripts for NS and ES | 
__init__.py. 
  It loads the configuration settings for Pyro (Pyro.config.* items).
  This way, whenever a module from the Pyro package is imported, it can use
  the config items right away. 
  Within the core package is also another package; Pyro.EventService.
  The event service is implemented here: the Event Server itself and the
  base classes for event publishers and listeners.
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.
protocol module 
  contains this. What the core module does contain is all stuff that realize the 
  core functions of Pyro:
ObjBasePyro_dyncall) 
    and remote attribute access (remote_getattr etc.)PyroURIPyroURI can be converted to and from a - human 
    readable - string.DynamicProxy and DynamicProxyWithAttrs__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 getAttrProxyForURIDaemonTCPServer 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.initClient and initServer functions perform
  necessary initialization. For instance, the server init code
  first checks the availability of the PYRO_STORAGE directory.NameServerLocator
 getNS method and you get a Pyro Proxy for the Name Server back.
NameServerProxy
 NameServerLocator.getNS.
NameServer and PersistentNameServer
 ns script that starts
 the Name Server.
NameValue and a NamedTree
 recursive data structure.
BroadcastServer
 LoggerBaseSystemLoggerPyro.util.Log 
    and this is Pyro's system logger that writes to Pyro's system logfile.UserLoggerArgParsergetopt 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.getGUIDgenguid_scripthelpergenguid command line utility, 
    which prints a new GUID.getPyroTracebackPyro.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). 
Pyro/EventService/Clients.py
 Subscriber and Publisher base classes defined
 that you can use to easily build publisher or listener clients for the ES.
Pyro/EventService/Server.py
 EventService Pyro object that is started by
 some utility code. This module is called by the es script that you can use
 to start the Event Server.
Pyro/ext/remote.py
 Pyro/ext/remote_nons.py
 Pyro/ext/daemonizer.py
 Pyro/ext/BasicNTService.py
 Pyro/ext/NS_NtService.py
 Pyro/ext/ES_NtService.py
 Pyro/ext/ServiceTest.py
 PyroURI has __hash__ method, so it can be used as key in a dict.
  However, PyroURIs are not immutable! So if it is used in a dict,
  and the URI changes, you're boned, because it ends up in the wrong
  hash bucket!
  DynamicProxy must have a __coerce__ method because Python 2.0.x
  appears to call that when comparing proxy objects. Python 2.1+
  doesn't call it. The __coerce__ method just returns (self,other) and this appears to work.
  DaemonServant: self.daemon object is cyclic reference to Daemon
  object, if weakrefs are not implemented in your Python version.
  | <previous | contents | next> | Pyro Manual |