How to combine callLater and addCallback?

blueFast picture blueFast · Nov 17, 2011 · Viewed 10.3k times · Source

This is so broken, I hope you are merciful with me:

reactor.callLater(0, myFunction, parameter1).addCallback(reactor.stop)
reactor.run()

myFunction returns a deferred.

I hope it is clear what I want to do:

  • as soon as the reactor is running, I want to call myFunction. That is why I am using 0 as the delay parameter. Is there no other way except callLater? It looks funny to pass it a delay of 0.
  • I want to stop the reactor as soon as myFunction has completed the task.

The problems that I have so far:

  • AttributeError: DelayedCall instance has no attribute 'addCallback'. Fair enough! How do I put a callback in the callback chain started by myFunction then?
  • exceptions.TypeError: stop() takes exactly 1 argument (2 given).

To solve the second problem I had to define a special function:

def stopReactor(result):
    gd.log.info( 'Result: %s' % result)
    gd.log.info( 'Stopping reactor immediatelly' )
    reactor.stop()

And change the code to:

reactor.callLater(0, myFunction, parameter1).addCallback(stopReactor)
reactor.run()

(still not working because of the callLater problem, but stopReactor will work now)

Is there really no other way to call reactor.stop except by defining an extra function?

Answer

Jean-Paul Calderone picture Jean-Paul Calderone · Nov 18, 2011

IReactorTime.callLater and Deferred are mixed together by twisted.internet.task.deferLater.

from twisted.internet import reactor, task

d = task.deferLater(reactor, 0, myFunction, parameter1)
d.addCallback(lambda ignored: reactor.stop())
reactor.run()