Credit: Duncan Grisby
You need to implement a CORBA server and client to distribute a processing task, such as the all-important network-centralized, fortune-cookie distribution.
CORBA is a mature object-oriented RPC protocol, and several CORBA
ORBs offer excellent Python support. This recipe requires multiple
files. Here is the interface definition file,
fortune.idl
:
module Fortune { interface CookieServer { string get_cookie( ); }; };
The server script is a simple Python program:
import sys, os import CORBA, Fortune, Fortune_ _POA FORTUNE_PATH = "/usr/games/fortune" class CookieServer_i(Fortune_ _POA.CookieServer): def get_cookie(self): pipe = os.popen(FORTUNE_PATH) cookie = pipe.read( ) if pipe.close( ): # An error occurred with the pipe cookie = "Oh dear, couldn't get a fortune\n" return cookie orb = CORBA.ORB_init(sys.argv) poa = orb.resolve_initial_references("RootPOA") servant = CookieServer_i( ) poa.activate_object(servant) print orb.object_to_string(servant._this( )) poa._get_the_POAManager().activate( ) orb.run( )
And here’s a demonstration of the client code, using the Python interactive command line:
>>> import CORBA, Fortune >>> orb = CORBA.ORB_init( ) >>> o = orb.string_to_object( ... "corbaloc::host.example.com/fortune") >>> o = o._narrow(Fortune.CookieServer) >>> print o.get_cookie( )
CORBA has a reputation for being hard to use, but it is really very easy, especially if you use Python. This example shows the complete CORBA implementation of a fortune-cookie server and its client. To run this example, you need a Python CORBA implementation (or two, as you can use two different CORBA implementations, one for the client and one for the server, and let them interoperate with the IIOP inter-ORB protocol). There are several free ones you can download.
With most ORBs, you must convert the IDL interface definition into Python declarations with an IDL compiler. For example, with omniORBpy:
$ omniidl -bpython fortune.idl
This creates Python modules named Fortune
and
Fortune_ _POA
to be used by clients and servers,
respectively.
In the server, we implement the CookieServer
CORBA
interface by importing Fortune_ _POA
and
subclassing the CookieServer
class that the module
exposes. Specifically, in our own subclass, we need to override the
get_cookie
method (i.e., implement the methods
that the interface asserts we’re implementing).
Then, we start CORBA to get an orb
instance, ask
the ORB for a POA
, instantiate our own
interface-implementing object, and pass it to the
POA
instance’s
activate_object
method. Finally, we call the
activate
method on the POA manager and the
run
method on the ORB to start our service.
When you run the server, it prints out a long hex string, such as:
IOR:010000001d00000049444c3a466f7274756e652f436f6f6b69655365727665723 a312e300000000001000000000000005c000000010102000d0000003135382e313234 2e36342e330000f90a07000000666f7274756e6500020000000000000008000000010 0000000545441010000001c0000000100000001000100010000000100010509010100 0100000009010100
Printing this is the purpose of the
object_to_string
call that our
recipe’s server performs just before it activates
and runs.
You have to give this value to the client’s
orb.string_to_object
call to contact your server.
Of course, such long hex strings may not be very convenient to
communicate to clients. To remedy this, it’s easy to
make your server support a simple corbaloc
URL
string, like the one used in the client example, but this involves
omniORB-specific code. (See the omniORBpy manual for details of
corbaloc
URL support.)
omniORBpy at http://www.omniorb.org/omniORBpy/.
Get Python Cookbook now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.