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

Ilya Etingof ilya at glas.net
Sun Jul 19 07:20:46 MDT 2009


>> But why main loop does not fire timed events when it has a chance to do
>> that? Note that my data processor takes 0.2 sec on each run, while my
>> timed event period is 1 sec.
>>
>> In other words, I'd understand this behavior if my data processor
>> would block main loop for a few periods of timed event, but this
>> is not the case.
>
> Because Twisted receives as many datagrams as possible before going back
> round the select loop (I think). So, 10 calls to datagramReceived are
> done (taking 10*0.2 seconds) before twisted gets a chance to schedule
> any other things.

Perhaps it works that way. And what makes things worse is that if datagram 
input rate is steady and higher than datagram processing time, the 
LoopingCall calls will never be invoked.

> As JP has said, you're not allowed to block the main loop like that, but
> I've seen similar problems with even relatively quick datagramReceived
> handlers (~0.1msec) under very high load (1000pps) resulting in a form
> of starvation. This isn't generally a problem with TCP calls due to flow
> control.

I do not think I'm blocking the main loop so much. I'd say I create a
condition when data processing time is a little bit longer than the period 
of incoming datagrams arrival.

By way of feedback, it looks to me that if reactor API would give 
user some degree of control on timed versus receiption calls sequencing, 
that would become a more-or-less elegant solution for issues like mine.

> The solution is:
>
>  def datagramReceived(...):
>    reactor.callLater(0, dorealwork, ...)
>
>  def dorealwork(self, ...):
>    ...
>
> This will schedule the "real" work as soon as possible in the next
> reactor loop, but also "fairly" in line with other calls.

Thanks for the hint!

With this callLater approach, timer function works better, though, still 
not absolutely fair:

timer called 1248008220.19
dorealwork 1248008220.81
dorealwork 1248008221.21
timer called 1248008221.41
dorealwork 1248008221.41
[ 2 dorealwork calls here ]
dorealwork 1248008222.01
timer called 1248008222.21
dorealwork 1248008222.21
[ 7 dorealwork calls here ]
dorealwork 1248008223.81
timer called 1248008224.01
dorealwork 1248008224.01
[ 17 dorealwork calls here ]
dorealwork 1248008227.61
timer called 1248008227.81
dorealwork 1248008227.81
[ 39 dorealwork calls here ]
dorealwork 1248008235.81
timer called 1248008236.02
dorealwork 1248008236.02
[ 87 dorealwork calls here ]
dorealwork 1248008253.62
timer called 1248008253.83

As we can see, timer call period seems to grow over high load.

thanks,
ilya




More information about the Twisted-Python mailing list