[Twisted-Python] reactor.callLater ponderings

Andrew Bennetts andrew-twisted at puzzling.org
Sun Dec 14 20:17:36 MST 2003


On Sun, Dec 14, 2003 at 05:41:37PM -0800, jjanecek at telusplanet.net wrote:
> I created this little program to test the callLater feacture in
> twisted.

It's not immediately clear to me exactly what you are trying to test with
this code... if you're just testing the resolution of callLater, then why
are you using threads?

callLater uses the timeout facility of select(2), poll(2) or whatever
underlying mechanism your reactor is using (you're using the poll reactor).
The poll system call takes a timeout in milliseconds, so I would expect that
on linux the theoretical minimum timeout you could get is determined by the
kernel's HZ value.  I don't know if the intervening layers of libc and
Python's runtime would have any impact... but given the way that Python does
multithreading, I *would* expect using threads in Python to have a
measurable impact.  Maybe try again without using threads?

Also, you call reactor.stop() from within a thread... I *think* that to be
correct, that you need to do reactor.callFromThread(reactor.stop).  I'm not
sure, though.

> def clock_pulse_thread() :
[...]
>     time.sleep(0.01)
>   
> reactor.callLater(frequency/1000.0,clock_pulse)
> reactor.run()
> 
> Now the instresting thing is that is windows the smallest
> increment i can call the callback with is like 10 ms. 

This is probably due to a hard-coded value on line 153 of win32reactor.py
(assuming you're using win32reactor and not just the default select
reactor..?)

> Also is there a place that I can use to set how frequent i want the reactor
> to check to see if a callLater function should be run ?

This question doesn't really make sense for most of the reactors.  The
reactor looks at the queue of callLaters to determine when it needs to next
wake up by to process the next one on time.  If there's activity on one of
its file descriptors (i.e. there's network traffic waiting to be read), it
will wake up sooner, process the traffic, and recalculate the timeout.  If
there is a new callLater added, it will recalculate the timeout.  The
timeout is passed to select or poll or kqueue or whatever, and the OS kernel
is in charge of making the system call return after the timeout has expired
if I/O hasn't already caused that to happen.

In the case of the win32reactor, there is a value with roughly the meaning
you have in mind (line 153 of win32reactor...)

> While on Linux (I tested using redhat 9.0 and mandrake 9.2) it does
> not seem to be accurate on anything under 1 second. I peeked inside the
> basereactor code and it does not seem to shed anylight. 

Is the consistent with both the default reactor (which uses select), and the
poll reactor?  Can you reproduce this without threads?

> I am running the clock pulse in a thread to simulate that it has to 
> wait for something.

As I've mentioned before, I don't really understand what you mean by this.

-Andrew.





More information about the Twisted-Python mailing list