1

I am trying to call a long (time-consuming) function through XMLRPC in Python.

My server.py:

import time
import SocketServer
import SimpleXMLRPCServer

PORT = 19989

class MyXMLRPCServer(SocketServer.ThreadingMixIn, SimpleXMLRPCServer.SimpleXMLRPCServer):
    pass

def hello():
    for x in xrange(10):
        yield "hello {}".format(x)
        time.sleep(1)

if __name__ == "__main__":
    server = MyXMLRPCServer(("", PORT),
                            requestHandler=SimpleXMLRPCServer.SimpleXMLRPCRequestHandler,
                            logRequests=True,
                            allow_none=True)
    server.register_function(hello)
    server.serve_forever()

and my client.py:

import xmlrpclib

HOST, PORT = "localhost",   19989

if __name__ == "__main__":
    my_server = xmlrpclib.ServerProxy('http://{}:{}'.format(HOST, PORT))
    print my_server.hello()

Is there a way to see the progress of the hello() function (e.g. logging) on the client side before it is finished?

user1156980
  • 115
  • 2

1 Answers1

0

Here's a similar question on SO, trying to achieve the same effect. Quoting its accepted answer:

If you want XML-RPC with long-running, early returning tasks, you probably need to rewrite your server into an asynchronous framework, like twisted

The 2nd answer from that shows a way to implement yield correctly in the XMLRPCServer. Esp since your current code gives the error: xmlrpclib.Fault: <Fault 1: "<type 'exceptions.TypeError'>:cannot marshal <type 'generator'> objects">.

Community
  • 1
  • 1
aneroid
  • 12,983
  • 3
  • 36
  • 66
  • Overriding the `do_POST` method gives the error `'str' object has no attribute 'next'` on the server and `xmlrpclib.ProtocolError: ` on the client. Also, I posted a separate question, because, if I understood the similar question correctly, the author wanted to yield one string before running the function. I wanted to yield an unspecified number of strings, while the function runs. – user1156980 May 02 '14 at 15:53
  • `yeild` turns your function into a generator. So you require one more function which iterates over what `hello` returns. You also need to restructure your client and server code similarly. Note the use of `while(1): server.handle_request()` instead of `server.serve_forever()`. – aneroid May 02 '14 at 16:04