[Twisted-Python] A pseudo-deferred class that can be canceled
glyph at twistedmatrix.com
Mon Jan 4 21:58:32 EST 2010
On Jan 4, 2010, at 9:22 PM, Terry Jones wrote:
> I just wrote the below for fun. It's untested :-)
> It's a class that you initialize with a callable (f), and which gives you
> back a deferred (d) that will fire when f fires. Alternately, you can fire
> d yourself by calling 'callback' or 'errback' on the class instance and
> passing a value. That value is returned via d.
I already lost you at the first sentence. The class below never appears to use 'self._f', and ... Deferreds are things that fire, I don't see how the callable (f) can fire. Can you rephrase your intent?
> The reason this is useful is that normally when you call a function that
> returns a deferred, you can't easily "cancel" the deferred because it is
> made and controlled by the function you called. The callback or errback on
> the deferred is (very likely) going to be called at some point. OTOH, in
> the class below you get to "cancel" the deferred by triggering it yourself.
> If you fire d in this way, then when the original deferred fires (if ever),
> its result is ignored.
I'm glad you're thinking about this, because it is an *extremely* thorny issue which I would really like to address one day. Many of the issues you're talking about were brought up, and various solutions suggested, then found problematic, then modified ad nauseam on <http://twistedmatrix.com/trac/ticket/990>. If you can read that discussion and make some sense of it, perhaps you can post a recommendation there, or at least a summary of the discussion so far so that I don't have to read the whole discussion again to remember what I think should happen next? :)
> I don't know why defer.Deferred.setTimeout is deprecated, but I guess it's
> partly to do with this control issue.
This is one of the reasons, but another major reason is that 'setTimeout' does not belong as a method of Deferred. If we did support cancellation somehow, the way to set a timeout would be to do 'reactor.callLater(5.0, myDeferred.cancel)'. Deferred was originally in twisted.python and it really should have remained there, decoupled from twisted.internet.
More information about the Twisted-Python