[Twisted-Python] If the errbacks of a canceled Deferred are called with error other than CancelledError, is this acceptable?

Tom Prince tom.prince at ualberta.net
Sat Jun 22 16:14:32 MDT 2013

Terry Jones <terry at jon.es> writes:

> Based on JP's comment, I still think I'm missing something here.

The original subject of this thread? There was a question of what errorq

> The problem that I was originally trying to address by getting 'cancel'
> into deferreds is that the control flow you mention gets totally stuck if a
> deferred never fires for some reason (this was happening to me in talking
> to the Twitter API).

.cancel as currently implemented addresses this, as calling cancel
causes the deferred to fire.

> This goes against the thinking that only the code that creates a deferred
> can fire it.

To allow anything else would be to break the abstraction

    d = Deferred()
    return d

    d = Deferred()
    d.addCallback(lambda x: x+1)
    return d

There is currently no way of distinguishing these to code
snippets. Allowing other code to callback/errback the deferred
would cause different results in the two cases.

> As API writers, we're used to being in control: we don't think it's a
> good idea if we create and return a deferred in a method and the code
> we return the deferred to then fires it itself.

It isn't so much a matter of control, as of abstraction. It isn't
uncommon for a single deferred to be pass through several systems, with
each stage adding more callbacks, changing the value that the next stage
will see in the callbacks they add.

If the "final" consumer could fire the deferred with any value, it would
need to know about all the stagse (or at least the first one) to know
what kind of value to put in.

> But as app writers consuming deferreds from these APIs, we
> want more control (I do, anyway).

Well, the consumer can't control the deferreds that it gets but, as your
code demonstrates, it is easy enough to create a new deferred that
behaves however the consumer wants. The fact that this isn't the same
object isn't signifiant, since the identity of deferreds isn't an
interesting thing.

> The ControllableDeferred2013 class I posted last night shows one
> way.

One comment about the code you posted: There doesn't really seem to be a
need to create a sepearte class, that forwards
.addCallback/.addErrback. You can just create a regular deferred that is
hooked hooked up in the appropriate way. (It may make sense for the
stage that sets this up to have an object, but it shouldn't pass it
along, it should just pass a regular deferred on). There are a few
places that accept deferreds that depend on the object being an instance
of deferred, which your object isn't.


More information about the Twisted-Python mailing list