[Twisted-Python] why deferred.setTimeout is not my favorite API method

Andrew Bennetts andrew-twisted at puzzling.org
Mon Apr 19 20:47:35 EDT 2004

On Mon, Apr 19, 2004 at 02:47:33PM -0400, Glyph Lefkowitz wrote:
> On Apr 17, 2004, at 8:25 PM, Andrew Bennetts wrote:
> >Ok, how about a compromise: if a creator a Deferred is able to cope 
> >with
> >timeouts, they should pass an "allowTimeouts=True" flag to the 
> >constructor.
> >Without it, the setTimeout method will raise an AssertionError.
> Gross.
> This is really my problem with setTimeout, really.  Right now it 

Luckily for you, I've already changed my mind on this, in favour of building
timeouts on top of some sort of cancellation support (see my reply to Bob).

> changes the semantics of .callback() and .errback() subtly - adding an 
> 'allowTimeouts' flag effectively changes the object's contract at 
> run-time.  I know that callback and errback do this already, but it's 
> implied that there is a single source of responsibility for calling 
> those methods.
> What we've really got here is two separate interfaces: IDeferred and 
> ITimeoutableDeferred.  I think that it might be appropriate to 
> implement one as a subclass, which does the twisted.internet-related 
> stuff.

Well, that's one way to look at it, I suppose.  Certainly, deferreds that
can support cancellation should be declared that way when they are created,
whether by a flag to the constructor or by using a subclass.  DeferredList
changes its behaviour pretty significantly based on constructor flags, and I
think we made the right decision there.  Cancellations aren't all that
similar to "fireOnOneErrback", though.  I don't have a strong preference on
flags vs.  subclasses here, except that I would tend to lean towards
whichever one has the simpler implementation.

> Perhaps we're putting the responsibility in the wrong place entirely.  
> Deferreds which can be timed out are often tracked with some kind of ID 
> in a map of Deferreds.  Maybe we should have a DeferredOperationManager 
> class which abstracts that functionality, removing the deferred from 
> the map when its callback/errback is called whether it's called by a 
> timeout or not...?  Constructing a TimeoutableDeferred would then 
> *require* a callback that, in the common case where a 
> DeferredOperationManager is used, would remove the Deferred from the 
> mapping.  Regular Deferreds would then have no setTimeout, and Bob 
> could use them without importing all of Twisted.

This idea sounds equally applicable to cancellable deferreds as to just
timeoutable deferreds.  I'd be happy to see any that eases the
implementation of creating Deferreds that can be cancelled -- I think that
that is really the hardest part of the whole problem (aside from desigining
an API everyone likes ;)


More information about the Twisted-Python mailing list