[Twisted-Python] how to get the result of a callLater-scheduled func?

Jean-Paul Calderone exarkun at divmod.com
Thu Mar 8 12:37:37 MST 2007


On Thu, 08 Mar 2007 19:39:21 +0100, Stefan Rank <list-ener at strank.info> wrote:
>Hi,
>
>I am scheduling a function with `callLater`.
>The function happens to return a Deferred (but it might return anything),
>and I was searching for an easy way to add a callback in order to
>get the result.
>I know a workaround by creating a Deferred first, adding the call as 
>callback and another callback to get the result, but this seems overly 
>complicated (see below).
>Am I missing something?
>
>So I set up some function to be scheduled (happens to be an inlineCallbacks- 
>generator for testing, but I think this should not be relevant here)::
>
>     >>> from twisted.internet import defer, reactor
>     >>> @defer.inlineCallbacks
>     ... def test(name):
>     ...     print name, 'start'
>     ...     yield # yielding a non-Deferred does nothing
>     ...     print name, 'end'
>     ...     yield defer.returnValue('uiuiui')
>
>I know this works::
>
>     >>> deftest = defer.Deferred().addCallback(test)
>     >>> jamesdelcall = reactor.callLater(0, deftest.callback, 'James')
>     >>> def stopverbose(whatever):
>     ...     print 'stopping, result:', whatever
>     ...     reactor.stop()
>     >>> deftest.addCallback(stopverbose)
>     >>> reactor.run()
>     James start
>     James end
>     stopping, result: uiuiui
>
>What I expected to be able to do::
>
>     >>> jamesdelcall = reactor.callLater(0, test, 'James')
>     >>> def stopverbose(whatever):
>     ...     print 'stopping, result:', whatever
>     ...     reactor.stop()
>     >>> jamesdelcal.gethisdeferred.addCallback(stopverbose) # <- MAGIC
>     >>> reactor.run()
>     James start
>     James end
>     stopping, result: uiuiui
>
>I looked at the code of `ReactorBase.callLater` and 
>`ReactorBase.runUntilCurrent`:
>Would it be possible to add a `Deferred` to `DelayedCall` (possibly created 
>lazily, or maybe even make DelayedCall a subclass of Deferred),
>so that such code is possible, or would this somehow destroy the mainloop 
>logic?

It's probably possible, but I'm not sure it's ideal.  It sounds like you
have a use-case for the `deferLater' function which has been proposed for
inclusion:

  http://twistedmatrix.com/trac/ticket/1875

With it, your example would look like either:

   d = deferLater(0)
   d.addCallback(lambda ignored: test('James'))
   d.addCallback(stopVerbose)

Or:

  d = deferLater(0, test, 'James')
  d.addCallback(stopVerbose)

Would that save enough typing to satisfy your use case?

Jean-Paul




More information about the Twisted-Python mailing list