xml-rpc/twisted question

G

Guyon Morée

Hi all,

Below this message you can see my code. It is a modified version of the
twisted xml-rpc server examples. I am trying to figure out how to implement
non-blocking methods. I found out that I have to use 'defer' to do that, but
I have no clue how to do this. Unfortunately the documentation could not
make this clear to(unless I am missing some docs). I have already added a
function called xmlrpc_block to represent a actual 'blocking function'.

I hope someone can show me how to modify this so the server does not block
any other clients when xmlrpc_block is called.

thanx,
Guyon

====================================================================
#TestServer.py

from twisted.web import xmlrpc, server
from twisted.internet import reactor

class Example(xmlrpc.XMLRPC):
"""An example object to be published."""

def xmlrpc_echo(self, x):
"""Return all passed args."""
return x

def xmlrpc_block(self, duration=10):
"""block the instance for a specified duration"""
import time
time.sleep(duration)
return "i slept %s seconds!" % (str(duration))


# this only runs if the module was *not* imported
if __name__ == '__main__':
r = Example()
reactor.listenTCP(7080, server.Site(r))
reactor.run()
 
A

Andrew Bennetts

Hi all,

Below this message you can see my code. It is a modified version of the
twisted xml-rpc server examples. I am trying to figure out how to implement
non-blocking methods. I found out that I have to use 'defer' to do that, but
I have no clue how to do this. Unfortunately the documentation could not
make this clear to(unless I am missing some docs). I have already added a
function called xmlrpc_block to represent a actual 'blocking function'.

I hope someone can show me how to modify this so the server does not block
any other clients when xmlrpc_block is called.

You'll have better luck asking this sort of question on the Twisted list, at
(e-mail address removed)... but here goes anyway :)

[...]
def xmlrpc_block(self, duration=10):
"""block the instance for a specified duration"""
import time
time.sleep(duration)
return "i slept %s seconds!" % (str(duration))

Basically, you can't do any blocking operation in the main thread (unless
it's acceptable to block your entire server!). Either resort to using
threads:

----
from twisted.internet.threads import deferToThread
from twisted.python import log

def xmlrpc_block(self, duration=10):
"""block the instance for a specified duration"""
import time
d = deferToThread(time.sleep, duration)
d.addCallback(lambda r: "i slept %d seconds!" % duration)
return d
----

Or even better, don't use a blocking operation in the first place:

----
from twisted.internet.defer import Deferred
from twisted.python import log

def xmlrpc_block(self, duration=10):
"""block the instance for a specified duration"""
import time
d = Deferred()
reactor.callLater(duration, d.callback,
"i slept %d seconds!" % duration)
return d
----

The trick with both of these is that Twisted's XML-RPC framework allows you
to return a Deferred instead of a result. When you return a Deferred,
Twisted won't return anything to the XML-RPC client until the Deferred is
called -- it adds a callback to the Deferred to send the response. This
gives you the oppurtunity to take as long as you need to answer the request
without blocking the rest of your server.

Note that Deferreds aren't magical. They are actually very simple objects
that represent a "deferred result", with convenient hooks to add chains of
callbacks (and "errbacks" for error handling) to them. In Twisted, when an
operation is likely to take a long time, but the function you call to invoke
that operation needs to return immediately, that function will return a
Deferred. See http://twistedmatrix.com/documents/howto/defer for more
information.

-Andrew.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,470
Messages
2,571,807
Members
48,797
Latest member
PeterSimpson
Top