twisted - interrupt callback via KeyboardInterrupt

后端 未结 2 1286
情歌与酒
情歌与酒 2021-01-13 16:37

I\'m currently repeating a task in a for loop inside a callback using Twisted, but would like the reactor to break the loop in the callback (one) if the user issues a Keyboa

2条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-13 17:15

    I got this working dandy. The fired SIGINT sets a flag running for any running task in my code, and additionally calls reactor.callFromThread(reactor.stop) to stop any twisted running code:

    #!/usr/bin/env python
    
    import sys
    import twisted
    import re
    from twisted.internet import reactor, defer, task
    import signal
    
    
    def one(result, token):
        print "Start one()"
        for i in xrange(1000):
            print i
            if token.running is False:
                raise KeyboardInterrupt()
                #reactor.callFromThread(reactor.stop) # this doesn't work
        print "End one()"
    
    def oneErrorHandler(failure):
        print "INTERRUPTING one(): Unkown Exception"
        import traceback
        print traceback.format_exc()
        reactor.stop()
    
    def oneKeyboardInterruptHandler(failure):
        failure.trap(KeyboardInterrupt)
        print "INTERRUPTING one(): KeyboardInterrupt"
        reactor.stop()
    
    def repeatingTask(token):
        d = defer.Deferred()
        d.addCallback(one, token)
        d.addErrback(oneKeyboardInterruptHandler)
        d.addErrback(oneErrorHandler)
        d.callback('result')
    
    class Token(object):
        def __init__(self):
            self.running = True
    
    def sayBye():
        print "bye bye."
    
    
    if __name__ == '__main__':
    
        token = Token()
    
        def customHandler(signum, stackframe):
            print "Got signal: %s" % signum
            token.running = False                # to stop my code
            reactor.callFromThread(reactor.stop) # to stop twisted code when in the reactor loop
        signal.signal(signal.SIGINT, customHandler)
    
        t2 = task.LoopingCall(reactor.callLater, 0, repeatingTask, token)
        t2.start(5) 
    
        reactor.addSystemEventTrigger('during', 'shutdown', sayBye)
    
        print "STARTING REACTOR..."
        reactor.run()
    

提交回复
热议问题