[Twisted-Python] why deferred.setTimeout is not my favorite API method
slyphon at twistedmatrix.com
Sat Apr 17 18:22:50 EDT 2004
This is response to issue 178 on the twisted tracker:
about the deferred method setTimeout.
The reason why I added a "DON'T USE THIS" to the docstring was that I
find that we are telling people this at least once a week. I think it
has more gravitas coming from the API documentation, as there is this
illusion that the people on IRC don't really know what they're talking
about, but if the author has marked something in the documentation, it
has a certain level of legitimacy.
I agree with spiv in the sense that it would be nice to have a minimal
interface that would provide this functionality. However, i think that
the level of control that is needed to pull this off properly is best
served by writing an explicit timeout method and accompanying call to
now, I'd like to present the idiom that we are try to encourage users to
follow every time we have to steer them away from setTimeout.
d = iReturnADeferred()
delayedCall = reactor.callLater(timeoutLen, onTimeout)
Here you see that each step is very explicit. You can see what happens
on success and on timeout (failure). I think one problem with setTimeout
is the handling of the IDelayedCall is something that a new user could
For instance, someone who hadn't /read/ the code of setTimeout, would
most likely miss the returned IDelayedCall, and wouldn't know to cancel
the pending timeout call in the event of success OR other failure. This
is _a crucial piece of the code path_, and setTimeout makes this easier
As from the Zen of Python Programming:
- Explicit is better than implicit
setTimeout hides a small piece of code that contains all of the
important conceptual elements that a user is required to understand
so that they may handle this side-exit condition properly.
- Special cases aren't special enough to break the rules
Delayed calls are orthogonal to deferreds.
Deferreds are a _reactive_ tool, they fire in response to an event
delayed calls are a _proactive_ tool, they cause events to fire
Mixing the two together for the special case of dealing with a
timeout is at best hairy and at worst ugly and confusing.
Timeout conditions are _not necessarily_ something that a user needs
to deal with 80% of the time they are working with deferreds.
- Simple is better than complex
The deferred api should contain absolutely necessary functionality.
Let's emulate the python language, not the python standard library
- There should be one, and preferrably only one way to do it
It is better to have users of our API use a widely-understood and
flexible idiom to accomplish this rather than a half-baked method
that saves them 8 lines of easily written and conceptually crucial
I would like to recommend that we document a best-practice idiom
in the deferred api documentation, and remove setTimeout.
- If an implementation is hard to explain it's a bad idea
Explaining to users how to properly use setTimeout takes more effort
than explaining to them how to use the tools that setTimeout employs
to achieve its functionality.
"In hindsight, I should've thought harder about the implications of
setTimeout before I committed it... but now it's there, I don't like the
idea of ripping it out unless we have a clearly better solution."
This is a less-than-optimal solution to an edge-case use of two
orthogonal parts of our API.
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".
slyphon AT twistedmatrix DOT com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Size: 189 bytes
Desc: This is a digitally signed message part
Url : http://twistedmatrix.com/pipermail/twisted-python/attachments/20040417/88af04b4/attachment.pgp
More information about the Twisted-Python