Question

My code looks like this:

... # class Site(Resource)
def render_POST(self,request)
   otherclass.doAssync(request.args)
   print '1'
   return "done" #that returns the HTTP response, always the same.

...

def doAssync(self,msg):
    d = defer.Deferred()
    reactor.callLater(0,self.doStuff,d,msg)
    d.addCallback(self.sucess)

def doStuff(self,d,msg):
    # do some stuff
    time.sleep(2)  #just for example
    d.callback('ok')

def sucess(msg):
    print msg

The output:

1

ok

So far, so good, but, the HTTP response (return 'done'), only happens after the delay (time.sleep(2)). I can tell this, because the browser keeps 'loading' for 2 seconds.

What am I doing wrong?

Was it helpful?

Solution

What you are doing wrong is running a blocking call (time.sleep(2)), while Twisted expects you to only perform non-blocking operations. Things that don't wait. Because you have that time.sleep(2) in there, Twisted can't do anything else while that function is sleeping. So it can't send any data to the browser, either.

In the case of time.sleep(2), you would replace that with another reactor.callLater call. Assuming you actually meant for the time.sleep(2) call to be some other blocking operation, how to fix it depends on the operation. If you can do the operation in a non-blocking way, do that. For many such operations (like database interaction) Twisted already comes with non-blocking alternatives. If the thing you're doing has no non-blocking interface and Twisted doesn't have an alternative to it, you may have to run the code in a separate thread (using for example twisted.internet.threads.deferToThread), although that requires your code is actually thread-safe.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top