[Twisted-Python] Deferred usage clarification
Andrew Bennetts
andrew-twisted at puzzling.org
Sun Jun 1 18:31:39 MDT 2003
On Sun, Jun 01, 2003 at 08:05:02PM -0400, Gary Poster wrote:
> Hi. A newbie question: I'd like a bit of clarification in Deferred
> usage. More specifically, it would be nice if one of the examples on
> the Twisted Deferred howto page used a real blocking call rather than a
> reactor.callLater.
>
> So, to see if I'm on the right track, I'd like to modify the third code
> example to use a sleep, to make it better parallel the first code
> snippet on the howto page.
>
> First, here it is from the page, without modification:
>
[...]
>
> Here's my modification. Is this the right usage?
No -- see below.
> -----8<-----8<-----8<-----
[...]
> class Getter:
> def getData(self, x):
> # this won't block
> d = defer.Deferred()
> reactor.callLater(0, self.doWork, x, d)
> return d
>
> def doWork(self, x, deferred):
> # churn, churn, churn
> time.sleep(2)
> deferred.callback(x * 3)
[...]
> -----8<-----8<-----8<-----
You're misunderstanding the purpose of Deferreds. They don't do any magic
to make blocking calls happen asynchronously.
A Deferred is simply a result that hasn't arrived yet. When the result of
some function can take some arbitrary amount of time to happen, it will
return a Deferred, rather than holding up the execution of the rest of the
program. A Deferred is a promise that a result (or failure) will arrive
eventually, and provides a convenient abstraction to attach callbacks to
that is far more usuable than riddling your code with functions that take a
method to callback when they're done.
How the result arrives later is entirely up to the code that returns the
Deferred. It might simply send an HTTP request, and wait for the result to
arrive off the network; it might query a database; it might split the work
up into small chunks that it schedules using callLater; or it might just use
deferToThread. All that matters is that at some point "d.callback(result)"
or "d.errback(failure)" is called (or you could call d.setTimeout(...) if
you aren't sure you want to wait indefinitely).
Does this make sense?
Regards,
-Andrew.
More information about the Twisted-Python
mailing list