[Twisted-Python] defer.AlreadyCalled error

Andrew Bennetts andrew-twisted at puzzling.org
Fri Mar 14 20:29:54 EST 2003


On Fri, Mar 14, 2003 at 09:06:37AM +0200, Dmitry Litovchenko wrote:
> Hello, all
> 
> Using my handcrafted socks5 client I've got the situation where my
> ClientFactory.clientConnectionLost and clientConnectionFailed get
> execution after errback is already called, so I get
> defer.AlreadyCalled error.
> 
> The fastest thing that solves it was try/except with raising error
> again if its not AlreadyCalled.
> 
> Is this solution correct or I should inherit some another method of
> ClientFactory or ClientProtocol to intercept this situation before its
> AlreadyCalled.

Your solution is fine.

I can think of another approach though, that is almost certainly too complex
and overkill for your problem, just in case you are interested:

Perhaps you could use a DeferredList instead, with fireOnOneCallback=1 (so
that results get passed immediately) and fireOnOneErrback=1 (so that errors
happen immediately).  

So what you'd do is create a DeferredList with two Deferreds:
  1. the Deferred you are using already
  2. a new Deferred that clientConnectionLost/Failed will call

Then add your callbacks and errbacks to the DeferredList instead of the
original Deferred.  DeferredList with fireOnOneErrback=1 will call its
errbacks as soon as any of its Deferreds errback, but won't raise
AlreadyCalled error no matter how many of its Deferreds errback.

The reason for also setting fireOnOneCallback=1 is to ensure that the
DeferredList doesn't wait for the second Deferred to callback, which should
never happen.

Basically, a DeferredList([...], fireOnOneCallback=1, fireOnOneErrback=1)
has the odd behaviour of effectively taking the first result (good or bad)
to arrive, and ignoring the rest.

In short, I think you're better off with the try/except :)

-Andrew.





More information about the Twisted-Python mailing list