xml-rpc

Martin P. Hellwig martin.hellwig at dcuktec.org
Sun Mar 14 11:17:54 CET 2010


On 03/14/10 08:14, ahmet erdinc yilmaz wrote:
> Hello,
>
> Recenetly we are developing a senior project and decide to use xmlrpclib.
> However I have some questions. In the documentation I could not find any
> clue about
> handling requests? Does the server handles each request in a separate
> thread? Or is
> there some queuing mechanism for client calls? Thanks in advance.
>
>
> --erdinc

How I usually tackle stuff like this:
[martin at aspire8930 /usr/home/martin]$ python
Python 2.6.4 (r264:75706, Jan 31 2010, 20:52:16)
[GCC 4.2.1 20070719  [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
 >>> import SimpleXMLRPCServer
 >>> help(SimpleXMLRPCServer)
<read it and somewhere at CLASSES it says>
CLASSES
 
BaseHTTPServer.BaseHTTPRequestHandler(SocketServer.StreamRequestHandler)
         SimpleXMLRPCRequestHandler
     SimpleXMLRPCDispatcher
         CGIXMLRPCRequestHandler
         SimpleXMLRPCServer(SocketServer.TCPServer, SimpleXMLRPCDispatcher)
     SocketServer.TCPServer(SocketServer.BaseServer)
         SimpleXMLRPCServer(SocketServer.TCPServer, SimpleXMLRPCDispatcher)

Aah so it is based on SocketServer, lets have a look at that:

 >>> import SocketServer
 >>> help(SocketServer)
Help on module SocketServer:
<reading it and then it says>

     There are five classes in an inheritance diagram, four of which 
represent
     synchronous servers of four types:

             +------------+
             | BaseServer |
             +------------+
                   |
                   v
             +-----------+        +------------------+
             | TCPServer |------->| UnixStreamServer |
             +-----------+        +------------------+
                   |
                   v
             +-----------+        +--------------------+
             | UDPServer |------->| UnixDatagramServer |
             +-----------+        +--------------------+

So the base of all these servers is BaseServer, hmm somebody must have a 
laugh right now :-)

Okay lets have a look at that then:

 >>> import BaseServer
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
ImportError: No module named BaseServer

Hmmm okay, lets have a look at the SocketServer source itself then, but 
where is it?
 >>> SocketServer.__file__
'/usr/local/lib/python2.6/SocketServer.pyc'

I bet that the non compiled file is in the same directory, let's have a 
look at it with less.

 >>> quit()
[martin at aspire8930 /usr/home/martin]$ less 
/usr/local/lib/python2.6/SocketServer.py

And there it says among other interesting stuff:

     # The distinction between handling, getting, processing and
     # finishing a request is fairly arbitrary.  Remember:
     #
     # - handle_request() is the top-level call.  It calls
     #   select, get_request(), verify_request() and process_request()
     # - get_request() is different for stream or datagram sockets
     # - process_request() is the place that may fork a new process
     #   or create a new thread to finish the request
     # - finish_request() instantiates the request handler class;
     #   this constructor will handle the request all by itself

     def handle_request(self):
         """Handle one request, possibly blocking.

         Respects self.timeout.
         """
         # Support people who used socket.settimeout() to escape
         # handle_request before self.timeout was available.
         timeout = self.socket.gettimeout()
         if timeout is None:
             timeout = self.timeout
         elif self.timeout is not None:
             timeout = min(timeout, self.timeout)
         fd_sets = select.select([self], [], [], timeout)
         if not fd_sets[0]:
             self.handle_timeout()
             return
         self._handle_request_noblock()

     def _handle_request_noblock(self):
         """Handle one request, without blocking.

         I assume that select.select has returned that the socket is
         readable before this function was called, so there should be
         no risk of blocking in get_request().
         """
         try:
             request, client_address = self.get_request()
         except socket.error:
             return
         if self.verify_request(request, client_address):
             try:
                 self.process_request(request, client_address)
             except:
                 self.handle_error(request, client_address)
                 self.close_request(request)


I leave the remaining parts of your question as an exercise :-)

-- 
mph



More information about the Python-list mailing list