[Twisted-Python] LoopingCall at a non-idling reactor

Ilya Etingof ilya at glas.net
Sat Jul 18 15:04:25 MDT 2009


After doing some more research, I've realised that my previous 
conclusion and complaint was indeed inaccurate. Sorry for that!

Now it looks to me that if my datagram receiver function takes some
time for data processing, rapidly coming datagrams tend to stack up and
my timer function is not getting called at time.

Here's example code:

from time import time, sleep
from twisted.internet import reactor, task
from twisted.internet.protocol import DatagramProtocol

def timerCbFun():
   print 'timer called', time()

loopingCall = task.LoopingCall(timerCbFun)
loopingCall.start(1, False)

class MyProtocol(DatagramProtocol):
   def datagramReceived(self, datagram, address):
     print 'datagramReceived', time()
     sleep(0.2) # simulate data processing

reactor.listenUDP(1024, MyProtocol(), '127.0.0.1')

reactor.run()

and here's its test run under relatively high incoming datagrams rate:

timer called 1247949866.62
timer called 1247949867.62
timer called 1247949868.62
datagramReceived 1247949869.16
datagramReceived 1247949869.36
datagramReceived 1247949869.56
datagramReceived 1247949869.76
datagramReceived 1247949869.96
.... no timer calls here ...
datagramReceived 1247949877.56
datagramReceived 1247949877.76
timer called 1247949877.96
timer called 1247949878.62
timer called 1247949879.62

So we missed eight timer calls in a row in the course of this run. What 
I need is that reactor would call my timer function at scheduled times
regardless of pending datagrams.

I do not think I'm using threads here.

thanks,
ilya

On Sat, 18 Jul 2009, Glyph Lefkowitz wrote:

> On Sat, Jul 18, 2009 at 3:33 PM, Ilya Etingof<ilya at glas.net> wrote:
>
>> I can't get Twisted reactor calling my function in a more or less
>> periodic fashion with the LoopingCall mechanics.
>>
>> With select()-based reactor, the LoopingCall object seems to call back my
>> timer function only on select() timeout. If I/O pace does not allow
>> select() to time out, LoopingCall never calls my function.
>
> This doesn't sound accurate to me.  If your reactor is constantly
> doing I/O, the timed call in question will be called when the
> appropriate amount of time has passed.
>
> Select does not "time out"; it just returns some result.  If it is
> returning purely do to the passage of time, then the result will be
> empty, but Twisted doesn't treat that type of result specially.
>
> Can you provide a short, sample program which demonstrates the
> behavior you're talking about?




More information about the Twisted-Python mailing list