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

exarkun at divmod.com exarkun at divmod.com
Sat Apr 17 19:59:22 EDT 2004

On Sat, 17 Apr 2004 18:22:50 -0400, Jonathan Simms <slyphon at twistedmatrix.com> wrote:
> [snip]
> ------------------------------------------------------
> d = iReturnADeferred()
> def onTimeout():
>     handleTimeoutCondition()
> delayedCall = reactor.callLater(timeoutLen, onTimeout)
> def success(value):
>     handleSuccess()
> def nonTimeoutFailure(reason):
>     handleErrorCondition()
> def cancelTimeout(val):
>     if delayedCall.active():
>         delayedCall.cancel()

      return val

> d.addBoth(cancelTimeout)
> d.addCallback(success)
> d.addErrback(nonTimeoutFailure)
> -------------------------------------------------------

  While I think the above is very close to being correct (it even fooled me into thinking it was correct for several minutes, during which I composed an alternate email expounding on how we might simplify users' lives by extracting the common portions of the above into a helper function), ultimately even it does not solve all the issues relating to timing out Deferreds.

  The problem is simply that "onTimeout" in the above code cannot be correctly defined by anyone except the person who defined "iReturnADeferred".

  The above pattern may be useful for framework implementors, but not users.  Framework implementors typically (though not always) understand how to handle timeout issues, so this is of little help.

  I think that users asking for help with setTimeout or with timing out Deferreds need to be handled in one of two ways:

  1) Direct them to APIs related to the features they wish to use with timeouts that already support timeouts directly (ie, not through setTimeout calls on the Deferreds they return).  Examples of such APIs include twisted.web.client.getPage and twisted.names.client.lookupAddress.

  2) If APIs for the feature they wish to use do not support timeouts, explain this.  Recommend that the user submit a patch or open an issue on the bug tracker, and/or apologize to them that Twisted is not yet perfect in every respect.

> [snip]
> It makes no sense to leave a sharp, pointy thing lying around for users
> to hurt themselves with, and to constantly tell them "DON'T USE THAT".

  I think that deprecating setTimeout is a good thing, even if several years must pass before we can actually remove it.  In addition to the reasons Jonathan gave, I will add this:

  setTimeout() is the only part of Deferreds that tie them to twisted.internet.  If it is removed, defer.py could (other issues, such as backwards compatibility and user consternation aside) be moved to the twisted.python package.  It also makes it that much easier to use Deferreds with a non-Twisted reactor.


More information about the Twisted-Python mailing list