[Twisted-Python] callLater(0) is A BIG LIE

James Y Knight foom at fuhm.net
Mon Nov 1 10:22:52 MST 2004


On Nov 1, 2004, at 5:41 AM, Jonathan Simms wrote:
> I'd like to offer some reflections on the reactor and facilitate some
> conversation on a subject that's been causing me much frustration:
>
>     the twisted idiom, "callLater(0)"
>
> While it seems that this is a DelayedCall, it really is a lie. It has
> nothing to do with time at all, it is a very *convenient* lie that we
> all have accepted, but is a lie nonetheless.
>
> We all know this means "call function f in the next reactor iteration",
> but the semantics of callLater have to do with time, not reactor
> iterations. In fact, in the API documentation, there is no reference to
> reactor iterations, at all.

I think you are somewhat mistaken, or at least, your message here is 
somewhat misleading. callLater(0) is not special, nor a lie. A reactor 
iteration looks at the current time _once_, and calls all DelayedCalls 
up until that point in time. This means that something like 
"callLater(1, foo); sleep(2)" will *also* not call foo ASAP after the 
function exits (even though its time has passed), but will wait until 
the next reactor iteration.

This is a general rule: no matter what the time value, callLaters() are 
supposed to happen after network I/O has next been processed. It is not 
brokenness, it's just a decision. You need to have *some* scheduling of 
timed events and IO events, and Twisted chose to alternate the two. 
That is a reasonable thing to do, as it helps prevent starvation of IO 
by timed events.

I take it libevent chose to always prefer timed events over network IO.

James





More information about the Twisted-Python mailing list