Writing a multithreaded multicall XML-RPC server

You can make your XML-RPC server accept multiple calls simultaneously. This means that multiple function calls can return a single result. In addition to this, if your server is multithreaded, then you can execute more code after the server is launched in a single thread. The program's main thread will not be blocked in this manner.

How to do it...

We can create a ServerThread class inheriting from the threading.Thread class and wrap a SimpleXMLRPCServer instance in an attribute of this class. This can be set up to accept multiple calls.

Then, we can create two functions: one launches the multithreaded, multicall XML-RPC server and the other creates a client to that server.

Listing 8.2 gives the code for writing a multithreaded, multicall XML-RPC server, as shown:

#!/usr/bin/env python
# Python Network Programming Cookbook -- Chapter – 8
# This program is optimized for Python 2.7.
# It may run on any other version with/without modifications.

import argparse
import xmlrpclib
import threading

from SimpleXMLRPCServer import SimpleXMLRPCServer

# some trivial functions
def add(x,y):
  return x+y

def subtract(x, y):
  return x-y

def multiply(x, y):
  return x*y

def divide(x, y):
  return x/y


class ServerThread(threading.Thread):
  def __init__(self, server_addr):
    threading.Thread.__init__(self)
    self.server = SimpleXMLRPCServer(server_addr)
    self.server.register_multicall_functions()
    self.server.register_function(add, 'add')
    self.server.register_function(subtract, 'subtract')
    self.server.register_function(multiply, 'multiply')
    self.server.register_function(divide, 'divide')

  def run(self):
    self.server.serve_forever()
  
def run_server(host, port):
  # server code
  server_addr = (host, port)
  server = ServerThread(server_addr)
  server.start() # The server is now running
  print "Server thread started. Testing the server..."

def run_client(host, port):
  # client code
  proxy = xmlrpclib.ServerProxy("http://%s:%s/" %(host, port))
  multicall = xmlrpclib.MultiCall(proxy)
  multicall.add(7,3)
  multicall.subtract(7,3)
  multicall.multiply(7,3)
  multicall.divide(7,3)
  result = multicall()
  print "7+3=%d, 7-3=%d, 7*3=%d, 7/3=%d" % tuple(result)

if __name__ == '__main__':
  parser = argparse.ArgumentParser(description='Multithreaded 
multicall XMLRPC Server/Proxy')
  parser.add_argument('--host', action="store", dest="host", 
default='localhost')
  parser.add_argument('--port', action="store", dest="port", 
default=8000, type=int)
  # parse arguments
  given_args = parser.parse_args()
  host, port =  given_args.host, given_args.port
  run_server(host, port)
  run_client(host, port)

If you run this script, you will see the output similar to the following:

$ python 8_2_multithreaded_multicall_xmlrpc_server.py --port=8000
Server thread started. Testing the server...
localhost - - [25/Sep/2013 17:38:32] "POST / HTTP/1.1" 200 -
7+3=10, 7-3=4, 7*3=21, 7/3=2 

How it works...

In this recipe, we have created a ServerThread subclass inheriting from the Python threading library's Thread class. This subclass initializes a server attribute that creates an instance of the SimpleXMLRPC server. The XML-RPC server address can be given via the command-line input. In order to enable the multicall function, we called the register_multicall_functions() method on the server instance.

Then, four trivial functions are registered with this XML-RPC server: add(), subtract(), multiply(), and divide(). These functions do exactly the same operation as their names suggest.

In order to launch the server, we pass a host and port to the run_server() function. A server instance is created using the ServerThread class discussed earlier. The start() method of this server instance launches the XML-RPC server.

On the client side, the run_client() function accepts the same host and port arguments from the command line. It then creates a proxy instance of the XML-RPC server discussed earlier by calling the ServerProxy() class from xmlrpclib. This proxy instance is then passed onto the MultiCall class instance, multicall. Now, the preceding four trivial RPC methods can be run, for example, add, subtract, multiply, and divide. Finally, we can get the result via a single call, for example, multicall(). The result tuple is then printed in a single line.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.37.151