09.11.2016 Views

Foundations of Python Network Programming 978-1-4302-3004-5

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

CHAPTER 18 ■ RPC<br />

such as <strong>Python</strong> integers, floats, strings, and tuples. For everything else, it passes across an object name<br />

that lets the remote side reach back into the client to access attributes and invoke methods on those live<br />

objects.<br />

This approach results in quite a bit <strong>of</strong> network traffic. It can also result in a significant delay if lots <strong>of</strong><br />

object operations have to pass back and forth between the client and server before an operation is<br />

complete. Tweaking security properly is also an issue. To give the server permission to call things like<br />

readlines() on the client’s own objects, I chose to make the client connection with a blanket assertion<br />

<strong>of</strong> allow_public_attrs. But if you are not comfortable giving your server code such complete control,<br />

then you might have to spend a bit <strong>of</strong> time getting the permissions exactly right for your operations to<br />

work without exposing too much potentially dangerous functionality.<br />

So the technique can be expensive, and security can be tricky if the client and server do not trust<br />

each other. But when you need it, there is really nothing like RPyC for letting <strong>Python</strong> objects on opposite<br />

sides <strong>of</strong> a network boundary cooperate with each other. You can even let more than two processes play<br />

the game; check out the RPyC documentation for more details!<br />

The fact that RPyC works successfully like this against vanilla <strong>Python</strong> functions and objects, without<br />

any requirement that they inherit from or mix in any special network capabilities, is an incredible<br />

testimonial to the power that <strong>Python</strong> gives us to intercept operations performed on an object and handle<br />

those events in our own way — even by asking a question across the network!<br />

RPC, Web Frameworks, Message Queues<br />

Be willing to explore alternative transmission mechanisms for your work with RPC services. The classes<br />

provided in the <strong>Python</strong> Standard Library for XML-RPC, for example, are not even used by many <strong>Python</strong><br />

programmers who need to speak that protocol. After all, one <strong>of</strong>ten deploys an RPC service as part <strong>of</strong> a<br />

larger web site, and having to run a separate server on a separate port for this on particular kind <strong>of</strong> web<br />

request can be quite annoying.<br />

There are three useful ways that you can look into moving beyond overly simple example code that<br />

makes it look as though you have to bring up a new web server for every RPC service you want to make<br />

available from a particular site.<br />

First, look into whether you can use the pluggability <strong>of</strong> WSGI to let you install an RPC service that<br />

you have incorporated into a larger web project that you are deploying. Implementing both your normal<br />

web application and your RPC service as WSGI servers beneath a filter that checks the incoming URL<br />

enables you to allow both services to live at the same hostname and port number. It also lets you take<br />

advantage <strong>of</strong> the fact that your WSGI web server might already provide threading and scalability at a<br />

level that the RPC service itself does not provide natively.<br />

Putting your RPC service at the bottom <strong>of</strong> a larger WSGI stack can also give you a way to add<br />

authentication if the RPC service itself lacks such a facility. See Chapter 12 for more information about<br />

WSGI.<br />

Second, instead <strong>of</strong> using a dedicated RPC library, you may find that your web framework <strong>of</strong> choice<br />

already knows how to host an XML-RPC, JSON-RPC, or some other flavor <strong>of</strong> RPC call. This means that<br />

you can declare RPC endpoints with the same ease that your web framework lets you define views or<br />

RESTful resources. Consult your web framework documentation and do a web search for RPC-friendly<br />

third-party plug-ins to see whether this is possible in your case.<br />

Third, you might want to try sending RPC messages over an alternate transport that does a better<br />

job than the protocol’s native transport <strong>of</strong> routing the calls to servers that are ready to handle them.<br />

Message queues, which are discussed in Chapter 8, are <strong>of</strong>ten an excellent vehicle for RPC calls when you<br />

want a whole rack <strong>of</strong> servers to stay busy sharing the load <strong>of</strong> incoming requests. If you explore a welldesigned<br />

RPC library like lovely.jsonrpc, you will find that you can define your own transports that<br />

send and receive information through your own mechanism <strong>of</strong> choice, rather than insisting that HTTP<br />

to a fixed IP address be used.<br />

319

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!