[Twisted-Python] Using a custom reactor in twisted trial for test cases?

Glyph Lefkowitz glyph at twistedmatrix.com
Mon Nov 2 01:12:27 EST 2009


On Nov 1, 2009, at 11:17 PM, Crispin Wellington wrote:

> On Fri, 2009-10-30 at 14:06 +0000, exarkun at twistedmatrix.com wrote:
>> It looks like your custom reactor is mainly in charge of making sure
>> stackless.schedule() gets called at least once every 0.1 seconds.  Is
>> that right?  If so, a much better approach would be to use
>> twisted.internet.task.LoopingCall rather than implementing a custom
>> reactor.
>>
>> Is there something undesirable about that (much simpler, less  
>> fragile)
>> approach?
>
> I tried using LoopingCall, but it does not work. It only calls the
> scheduler once. I think this has to do with the fact that the  
> stackless
> scheduler needs to be interwoven with the twisted reactor pump.

LoopingCall does "interweave" the function that you pass to it with  
the "twisted reactor pump".  If you were using it correctly, it would  
work, as the page that you link to indicates :).

What do you mean "does not work"?

> There is
> more info about why it has to be done like this here:
> http://code.google.com/p/stacklessexamples/wiki/StacklessTwisted

This example, linked from that page:
<http://stacklessexamples.googlecode.com/svn/trunk/examples/twisted/TwistedTimerReactorControl.py 
 >
is roughly the same as what exarkun recommended.

These examples aren't the greatest, because they tend to assume that  
you _always_ have Stackless code that's ready to run, and you want to  
run at some number of "frames per second".  For simple examples this  
makes sense, but for a system architecture this is a limiting  
approach.  If your stackless application wants to sit idle and wait  
for input, you're still going to wake up once every 1/30 second and  
checking to see if there's anything to do, burning CPU cycles and  
battery life.  Also, if you want to run *faster* than the arbitrary  
timeout you've selected (1/30 second can be a very long time,  
especially if you're doing something pseudo-realtime, like audio  
playback) you're out of luck.

Better would be to have tasklets schedule *themselves* for when they  
want to run.  If you just want to allow the rest of the reactor a time- 
slice, twisted.internet.task.cooperate() will allow you to schedule a  
potentially arbitrary number of tasks which want to run "as often as  
possible" without completely swamping the reactor; you can suspend  
that task by returning a Deferred which only fires when more stackless  
stuff is actually ready to run.




More information about the Twisted-Python mailing list