9. Pyro Change Log
(most recent entries at the end)
Pyro version 0.1 has been lost in the dust. It wasn't suited for publication anyway, I guess :-)
Pyro 0.2
First working release. Only static proxies and very little configurability.
Pyro 0.3
- MAJOR: added Dynamic Proxies! Clients don't need to have a precompiled proxy file available any more! Check out
core.getProxyForURI/DynamicProxy
.
- MAJOR: reworked the configuration possibilities. Check out
__init__.py
.
- Moved config items to a class in
__init__.py
. They are accessed using 'Pyro.config.<item>
'.
- Made the port and broadcast port configurable independently. The command lines now accept options to specify either or both ports.
- naming: added delay in broadcast loop (wait a little for replies to arrive), Naming Service now returns PyroErrors instead of regular exceptions.
- core: Cleaned up the Pyro exception passing, added
DynamicProxy
and getProxyForURI
- pyroc: fixed bug in method output code (could forget a comma)
- nsc: fully rewrote the parsing code to use the
util.ArgVParser
- scripts: the Window
.bat
files now use %$
- added
util.py
, which contains a basic sys.argv
parser like getopt()
.
Pyro 0.4
- naming: changed broadcast server to reflect changes in Python 1.5.2's
SocketServer
module. Pyro now requires this new SocketServer
module (which works with previous Python versions, too, so you could only replace the SocketServer
module and keep the rest of your Python installation intact).
- naming: fixed bugs when reporting exceptions ('entry already exists' and 'not found').
- util: added
getUUID
function, and a script genuuid
.
- core: Pyro objects are now identified by a full UUID, instead of a simple Python
id()
. This should prevent nasty object ID problems, especially later when persistent naming and object activation will be implemented.
Pyro 0.5
- MAJOR: the Pyro Naming Service now is a Pyro object itself, too. It can be accessed through its Pyro interface.
- More specific exceptions (
ProtocolError, URIError, DaemonError, NamingError
...)
- It is now possible to connect objects without the presence of a Naming Service.
- core: the Daemon can now handle requests for others too, by a callback mechanism. Also removed up the server-side exception trace info when the exception is generated on purpose, and added a nice message when the daemon cannot be started.
- naming: many changes to make the Name Server a Pyro object itself. Finding the NS is now done through the
NameServerLocator
, which returns a regular Pyro proxy for the NS. No NameServerClient
is needed anymore.
- util: tweaked the way the timestamp in URIs is generated.
- config: more configurable items.
- scripts:
Pyroc.bat
now uses %$
, too (oops!)
Pyro 0.6
- Added
xnsc
, a naming service control tool with a GUI (uses Tkinter
).
- The naming service can be launched in 'persistent mode': it will keep the naming directory in a persistent database on disk. EXPERIMENTAL!
- core: added 2 configuration variables in
Pyro.config
: PYRO_PATH
and PYRO_STORAGE
.
- core: added method to
ObjBase
to set a fixed (persistent) object UUID.
- core: slight change in the init code of
PyroURI
, it can now be created directly from a URI string, instead of using initFromString
.
- core: the
Daemon
now has preliminary support for persistent objects: connectPersistent
and disconnectPersistent
methods were added. LIKELY TO CHANGE!
- naming: added a persistent name server class
PersistentNameServer
. Also added some code to deal with this when using the 'ns
' command line tool: a new option '-db
' has been added to specify persistent mode.
- naming: the broadcast server now binds on '' instead of the hostname. This appears to be more compatible (on some systems it was impossible to connect to the broadcast server).
- naming: implemented graceful shutdown command. The server also uses a timeout loop for the requests (because otherwise ^C wouldn't break gracefully on WinNT - Duh).
- scripts:
nsc
(and xnsc
) now print a sorted list (and have the shutdown command).
- scripts: the
.bat
files now won't echo the python command anymore.
- utils:
ArgParser
changed to use None
instead of 1
when no arguments are given to a certain option.
- test:
testclient
will use dynamic proxy automatically if no static proxy is found. Also, it will try a direct connect if the NS lookup by broadcast fails.
Pyro 0.7
- bumped all versions to 0.7
- NOTE: because of some changes you will have to generate your proxies again with
pyroc
!
- core: separated the Exception types and the protocol adapters to
errors.py
and protocol.py
.
- util: added a
Logger
object, Log
. It is used troughout Pyro to log messages, warnings and errors. You can configure the logfile and the trace level settings with some new configuration options. Ofcourse you can use it for your own logging purposes too.
- init: changed the way configuration items are set up. If a corresponding environment variable exists, that value is used. Otherwise the default applies. This works for all configuration options except
PYRO_NS_NAME
because that is a registered name and should not be changed.
- naming: the naming server now writes its URI to a special output file. This can be used to contact the naming server if you can't use the broadcast locator for some reason.
- uuids: renamed UUID to GUID (Globally Unique ID). You can never be sure that your ID is Universally Unique, so I changed the name. Also, the
genuuid
scripts have been renamed to genguid
.
- changed default pickling mode to binary, to improve performance. A new configuration option lets you choose between ASCII or binary.
- pyroc: fixed a problem where the '
self
' argument of a member function had a different name. Pyroc now uses 'S
' everywhere.
- pyroc: added support for inherited classes. A module within a Python packages is not yet supported as input!
- pyroc: explicit checks against special Python methods
__xxx__
. They are not allowed in the proxy code.
- MAJOR documentation update.
Pyro 0.8
- A few fixes in the source comments.
- Added separate user logging facility and fixed small bug in logger code (it was too picky on the arguments).
- Moved some protocol dependend code from
core.py
to protocol.py
- New exception model! See documentation! Basically, every exception on the server side will be catched and raised on the client side.
- Naming server and the
nsc
and xnsc
tools are more strict with the names and URIs they allow.
- GUIDs are now 128 bit (instead of 144) and Pyro can use Windows GUIDs on the Windows platform. This is configurable trough a new configuration item
PYRO_USE_WIN32GUID
. This is not the default and will work only on the Windows platform, because the Python COM extension is used for this.
- New
genguid
script with '-w
' argument to generate a Windows GUID if possible.
- Fixed some things to allow for special 'localhost' optimization (the reduced overhead of some network implementations when using 'localhost' instead of the real hostname). The changes are:
- Pyro daemon now binds on '' instead of hostname. Previously, URIs with the 'localhost' hostname couldn't be bound.
- The
PyroURI
class has a new optimizeLocalhost
method, which -if possible- optimizes the URI for localhost addressing.
This also paves the way for more optimizations might be added when Pyro detects a local URI. (for instance, using IPC instead of going trough the network)
- Implemented Delegate pattern for remote object implementations. Instead of subclassing your object implementation from
Pyro.core.ObjBase
, you just create a Pyro.core.ObjBase
object and tell it to use another object as a delegate.
- New
ArgParser
in util.py
, to support more convenient script arguments. A few scripts have slightly altered syntaxes now, which should be more convenient. The old syntax should still work however.
- Documentation updates. Major addition is the new chapter with a practical guide about how to develop Pyro programs.
Pyro 1.0
- MAJOR: Reimplemented the PYRO protocol. It now uses a MUD-like system instead of a webserver-like system.
The protocol used to create a new socket connection for each method call. This is inefficient and resource hungry.
The new implementation uses a single socket for each Pyro object, and all method calls and replies are passed over this connection. The connection remains active until the object is no longer needed.
The new implementation no longer has the serious problem that the previous implementation had on most machines: when a lot of method calls were made,
the system would crash with some sort of 'resource unavailable' or 'out of memory' error. The new protocol is also faster than the previous one on all systems.
- Because of the new protocol, I think Pyro now deserves the version 1 status: bumped all version numbers to 1.0
- The Pyro
Daemon
inherits from the new TCPServer
base class (in protocol.py
). This server replaces the SocketServer.TCPServer
.
The new server keeps a list of active connections, while the old one operated like a webserver: it created a new socket connection for each request.
- Pyro Daemon has been adapted to the new protocol.
- NOTE: The new PYRO protocol is incompatible with the older versions. Communication is impossible between different Pyro versions. You should upgrade all Pyro installations to the new version.
However, user code does not have to be changed. Old code still runs on top of the new implementation (the API has not been changed).
- The Windows .bat scripts now use
#*
instead of #$
(which didn't work on the standard Windows95/NT command prompt).
xnsc
handles communication errors better.
- Organized the tests in the
test
directory and added some readme files. Also added some more tests/examples.
- Moved some socket code out of other modules to
protocol.py
. Now only naming.py
and protocol.py
have socket code.
- Removed the
NULLAdapter
.
- Removed the pickling of NS system commands. They're simple strings now.
- Added socket send/receive helper functions in
protocol.py
for robust data transmission. The new protocol code uses them. Performance is lower but the new code should guarantee correct behaviour even at high network loads with many packet losses and fragmentations.
- New exceptions
SocketClosedError
and ServerFullError
.
- Removed
RemotePyroException
(unused).
- Small change in the
xnsc
GUI: better resizing
- The new protocol enforces a limit on the number of simultaneous connections to each Pyro daemon. This is for protection of the server machine. There is a new configuration item
PYRO_MAXCONNECTIONS
which sets this limit. Currently the default is 200.
- The
unregister
method of the naming service now raises a NamingError
when the name is not known. I added this because usually this signals a typo in the calling code (it should never unregister an unknown name).
- Documentation updates; manual is finished except for the implementation chapter.
- MAJOR: Naming Service now has a hierarchical namespace. It has groups, which can contain other groups or names. By default, a dot ('.') in a name is the group separator, so that "group1.group2.name" is a hierarchical name.
Notice that this is much like DNS's host/domain name scheme, but in reverse order, rather like a directory structure in a disk file system.
The big gain from all this is that you can have different "domains" (namespaces) in your Pyro environment. With a simple change of the default namespace group your system uses a different "domain" and the object names will not interfere with other systems (provided your namespace group is unique).
For an application of this, see the new test programs, which now all use the ':test' namespace group. Also, it opens the gates for an even more sophisticated naming service: a distributed federated hierarchical nameservice (wow!! :-)
- The default or de facto namespace group is ":Default". This means that Pyro code which does not (yet) use the new naming scheme will wind up registering all its object names in this namespace group. That's nice because this is a simple way to avoid name clashes with legacy Pyro code and new code.
- Adapted the NS proxy to enforce the default group on all names that are not absolute from the root. It is now required that all names passed to the NS are absolute (fully expanded), the hand coded NS proxy takes care of this.
Note that a proxy obtained for the NS by other means does not have this feature and will likely break your code! Notably, the use of a dynamic proxy for the NS will no longer work correctly. Always use the static proxy from the
naming
module.
- Added configuration item
PYRO_NS_GROUPSEP
, which is the character that separates groups in names. By default it is a dot ('.'), but if this proves incompatible with existing naming schemes (which use dots in the names), just change it to something else.
Notice that this item is only examined once: at startup time. You have to restart the Naming Service if you change this item.
- Added configuration item
PYRO_NS_DEFAULTGROUP
, which is the default group name in which names are located. This simplifies partitioning your name space greatly.
Notice that the Name Server proxy code is hand crafted to enforce this name.
- Added configuration item
PYRO_NS_ROOTCHAR
, which is the default escape character at the beginning of names, which indicates the name is absolute from the root.
- Changed the config item for the name server name to include a root character. Existing code should not break (if it does, you probably didn't use
PYRO_NS_NAME
...
- Extended the name server object with three new remote methods for hierarchical naming support:
createGroup
, deleteGroup
and list
. Furthermore, status
has been renamed to flatlist
. This suggests better what it does: return a flat dump of the namespace.
- Extended
nsc
and xnsc
with the new naming service features: list, creategroup and deletegroup commands. (The old list command was renamed to listall).
- Simplified dynamic proxy. It used to create a invocation object with each method call, this is no longer so.
- Fixed bug in
protocol.py
where a KeyError
in a method invocation was always treated as if a method call on an unknown object was tried, even when the object was correct (but raised a KeyError
)
- Naming service will no longer crash when an unexpected exception occurs while it is running. It will log and print the error and resume operations. A ctrl-c (
KeyboardInterrupt
) will still abort it, however, as will sending a shutdown command.
- Small change in the Daemon in
core.py
. If a ProtocolError is detected (for instance, an invalid header), the connection is dropped and operations are resumed. Pyro used to block or crash when a non-Pyro client connected, such as a plain telnet or a web browser pointed at Pyro's socket.
- Test servers and clients are now using common code bases. They're registering their names in a new "
:test
" group (namespace) too, to help avoid conflicts with your own names. Servers will no longer crash if their name is already registered (they just register again).
- Fixed a few small errors in some of the test programs, and created an electronic banking example to be a nice starting point for Pyro applications.
- Fixed bug in some default arguments to functions, where config items were used. Now they are parsed at use instead of at module import time.
- Added '
-k
' switch to ns
that will start the NS in a mode in which it ignores shutdown requests sent by nsc
. This is a crude form of security, to protect the NS for malicious shutdowns.
- Documentation updates about the new naming scheme.
- New example added that uses the new naming functions.
- Configuration files! You can now use a configuration file that contains all required Pyro config options. It's no longer necessary to use a big list of environment variables.
- New configuration item
PYRO_CONFIG_FILE
. Only usefull as environment variable, it points to the configuration file Pyro has to use.