[Twisted-Python] defer.AlreadyCalled error

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. -- Best regards, Dmitry mailto:kwaker@uch.net

On Fri, Mar 14, 2003 at 09:06:37AM +0200, Dmitry Litovchenko wrote:
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.

On Fri, Mar 14, 2003 at 09:06:37AM +0200, Dmitry Litovchenko wrote:
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.
participants (2)
-
Andrew Bennetts
-
Dmitry Litovchenko