tags:

views:

64

answers:

2

I am trying to teach myself some rudimentary Twisted programming thanks to this tutorial and many others. I have come to this current example which I Can't figure out why it's doing what it is doing.

Short summary: I have instantiated three reactors that count down from 5 to 1 with different delays in their counting. Only thing is, it looks like when the first counter (with the shortest delay) gets to 0, it stops not only its own reactor, but all the others.

#!/usr/bin/env python

class Countdown(object):

    counter = 5

    def count1(self):
        from twisted.internet import reactor
        if self.counter == 0:
            reactor.stop()
        else:
            print self.counter, '...1'
            self.counter -= 1
            reactor.callLater(1, self.count1)

    def count2(self):
        from twisted.internet import reactor
        if self.counter == 0:
            reactor.stop()
        else:
            print self.counter, '...2'
            self.counter -= 1
            reactor.callLater(0.5, self.count2)

    def count3(self):
        from twisted.internet import reactor
        if self.counter == 0:
            reactor.stop()
        else:
            print self.counter, '...3'
            self.counter -= 1
            reactor.callLater(0.25, self.count3)

from twisted.internet import reactor

reactor.callWhenRunning(Countdown().count1)
reactor.callWhenRunning(Countdown().count2)
reactor.callWhenRunning(Countdown().count3)

print 'Start!'
reactor.run()
print 'Stop!'

Output

Start!
5 ...1
5 ...2
5 ...3
4 ...3
4 ...2
3 ...3
2 ...3
4 ...1
3 ...2
1 ...3
Stop!

I was under the impression that while all three counters should count down at their own speed and complete their 5->0 progression, the program would wait for them all to complete before exiting. Am I misunderstanding something in the ways of Twisted here?

+1  A: 

I am unfamiliar with twisted, but from skimming google results it looks like reactor is an event loop. You only have one of them, so the first counter to hit reactor.stop() stops the loop.

To do what you want you need to remove the reactor.stop() calls and structure things so that when the last timer hits the end it, and only it, calls reactor.stop()

Brian C. Lane
Brian, thanks for the tip. Maybe I am just not familiar enough with Twisted's methods, but how would I code a conditional looking for the 'last timer'? I thought of using getDelayedCalls, but that only seems to work with callLater usage, and not with callWhenRunning.
jfofo
A: 

He talks a bit about that in part 3. You might be mixing up "starting three reactors in one server" and "starting three different servers". The examples suggest to do the latter; your code is attempting to do the former.

Basically the reactor is a singleton, and cannot be restarted once stopped. So you can only have one per process, or maybe one per thread.

Instead of starting three reactors, you want to set up three different timed callbacks on the same reactor. They will all get fired at the appropriate time.

intuited