Foundations of Python Network Programming

(WallPaper) #1
Chapter 18 ■ rpC

343

Using named tuples (as they exist in the most recent versions of Python) might be an even better way to marshal
such values before sending them, if you find yourself creating and destroying too many dictionaries to make this
transformation appealing.


Talking About Objects: Pyro and RPyC

If the idea of RPC was to make remote function calls look like local ones, then the two basic RPC mechanisms
discussed previously actually fail pretty spectacularly. If the functions you were calling happened to only use basic
data types in their arguments and return values, then XML-RPC and JSON-RPC work fine. But think of all of the
occasions when you use more complex parameters and return values instead! What happens when you need to pass
live objects? This is generally a very hard problem to solve for two reasons.
First, objects have different behaviors and semantics in different programming languages. Thus, mechanisms
that support objects tend to either be restricted to one particular language or offer an anemic description of how an
“object” can behave that is culled from the lowest common denominator of the languages it wants to support.
Second, it is often not clear how much state needs to travel with an object to make it useful on another computer.
True, an RPC mechanism can just start recursively descending into an object’s attributes and getting those values
ready for transmission across the network. However, on systems of even moderate complexity, you can wind up
walking most of the objects in memory by doing simple-minded recursion into attribute values. And having gathered
up what might be megabytes of data for transmission, what are the chances that the remote end actually needs all of
those data?
The alternative to sending the entire contents of every object passed as a parameter, or returned as a value, is
to send only an object name that the remote end can use to ask questions about the object’s attributes if it needs to.
This means that just one item of a highly connected object graph can be quickly transmitted, and only those parts
of the graph that the remote site actually needs wind up getting transmitted. However, both schemes often result in
expensive and slow services, and they can make it very difficult to keep track of how one object is allowed to affect the
answers provided by another service on the other end of the network.
In fact, the task that XML-RPC and JSON-RPC force upon you (i.e., breaking down the question you want to ask
a remote service so simple data types can be easily transmitted) often winds up being, simply, the task of software
architecture. The restriction placed on parameter and return value data types makes you think through your service to
the point where you see exactly what the remote service needs and why. Therefore, I recommend against jumping to
a more object-based RPC service simply to avoid having to design your remote services and figure out exactly which
data they need to do their job.
There are several big-name RPC mechanisms like SOAP and CORBA that, to varying degrees, try to address the
big questions of how to support objects that might live on one server while being passed to another server on behalf
of a client program sending an RPC message from yet a third server. In general, Python programmers seem to avoid
these RPC mechanisms like the plague, unless a contract or assignment specifically requires them to speak these
protocols to another existing system. They are beyond the scope of this book; and, if you need to use them, you should
be prepared to buy at least an entire book on each such technology, as they can be that complex!
However, when all you have are Python programs that need to talk to each other, there is at least one excellent
reason to look for an RPC service that knows about Python objects and their ways. Python has a number of very
powerful data types, so it can simply be unreasonable to try “talking down” to the dialect of limited data formats like
XML-RPC and JSON-RPC. This is especially true when Python dictionaries, sets, and datetime objects would express
exactly what you want to say.
There are two Python-native RPC systems that I should mention: Pyro and RPyC. The Pyro project can be found
at http://pythonhosted.org/Pyro4/. This well-established RPC library is built on top of the Python pickle module,
and it can send any kind of argument and response value that is inherently pickle-able. Basically, this means that if an
object and its attributes can be reduced to its basic types, then it can be transmitted. However, if the values you want
to send or receive are ones that the pickle module chokes on, then Pyro will not work for your situation. (Though you
could also check out the pickle documentation in the Python Standard Library. This library includes instructions on
making classes pickle-able if Python cannot figure out how to pickle them itself.)

Free download pdf