[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