[Twisted-Python] deferToThread help

Jean-Paul Calderone exarkun at divmod.com
Wed Apr 29 15:02:33 EDT 2009


On Wed, 29 Apr 2009 11:45:09 -0700, Minesh Patel <minesh at gmail.com> wrote:
>Sorry if this is a newbie question.
>
>I have a blocking function that I defer to thread, let's say 'foo' and
>I would like to add a callback that gets called after say 10 minues
>after Thread finishes
>
>def foo():
>   # Blocks for a while
>
>def bar():
>   # Do some stuff
>
>d = threads.deferToThread(foo)
>d.addCallback(bar) # How can I add timing to the callback???
>
>Currently I have the following code which works but doesn't account
>for the threads execution time:
>
>reactor.callInThread(self.bootIso, self.iloIp, pathToIsoRename)
># 10 minutes sleep
>d = task.deferLater(reactor, 600, bar)
>

You just need to combine the relevant parts of these two solutions.  First,
the deferToThread call which will let you know when the task in the thread
has completed (this is not when the thread exits, because deferToThread uses
a thread pool and threads are re-used for many tasks):

    fooComplete = deferToThread(foo)

Next, when `foo´ is finished, you want to wait 10 minutes.  You had the
right idea with deferLater, but you don't want to call it until `foo´ is
finished:

    def waitTenMinutes(result):
        return deferLater(reactor, 600, lambda: result)
    fooComplete.addCallback(waitTenMinutes)

Finally, after a ten minute delay, you want to call `bar´:

    fooComplete.addCallback(bar)

Since a Deferred has a chain of callbacks which are called one after the
other, and since return a Deferred from a callback causes things to wait
for the result of that new Deferred before moving on to the next callback
in the original chain, combining deferToThread, deferLater, and bar as
above will give you the desired behavior.

Jean-Paul




More information about the Twisted-Python mailing list