[Twisted-Python] callLater(0) is A BIG LIE
James Y Knight
foom at fuhm.net
Mon Nov 1 12:22:52 EST 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.
More information about the Twisted-Python