2012-11-20 27 views
6

所以我正在写一个小脚本来和Deluge一起使用。 Deluge使用Twisted,但我对于它的工作原理并没有很好的把握。通常情况下,我只会查看更多信息,但开始使用Twisted将需要很长的时间,并且超出了这个小项目的范围。所以我想我会在这里问。扭曲的反应器停止,但程序不会结束?

现在,我有这个代码。我会尽力解释我需要

import base64 

import processargs 

from deluge.ui.client import client 
from twisted.internet import reactor 

from deluge.log import setupLogger 
setupLogger() 

options = processargs.readConfig(os.path.expanduser("~/.deluge-automator")) 

d = client.connect(
    host=options['host'], 
    port=int(options['port']), 
    username=options['username'], 
    password=options['password'] 
) 

def start(): 
    #other code 

    t = client.core.add_torrent_file(tfile, 
            base64.encodestring(data), None) 

    t.addCallback(on_torrent_added_success, tfile) 
    t.addErrback(on_torrent_added_fail) 


def handle_stop_signal(SIGNAL, stack): 
    client.disconnect() 
    reactor.stop() 


def on_torrent_added_success(result, tfile): 
    #other code 
    start() 


def on_torrent_added_fail(result): 
    print "Add torrent failed!" 
    print "result: ", result 


def on_connect_success(result): 
    #other code 
    start() 


d.addCallback(on_connect_success) 


def on_connect_fail(result): 
    print "Connection failed!" 
    print "result: ", result 


d.addErrback(on_connect_fail) 

signal.signal(signal.SIGTERM, handle_stop_signal) 
signal.signal(signal.SIGINT, handle_stop_signal) 

reactor.run() 

成功增加洪流,它应该回到开始()帮助specifig部分,确实如此,但我认为它失去了反应器什么的。因为现在每当临危一个SIGTERM或SIGINT,反应堆关闭,但不退出程序:

± % python2 main.py 
Connection was successful! 
result: 10 
^C^CConnection failed! 
result: [Failure instance: Traceback: <class 'twisted.internet.error.ReactorNotRunning'>: Can't stop reactor that isn't running. 
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks 
/usr/lib/python2.7/site-packages/deluge/ui/client.py:412:__on_login 
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:368:callback 
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:464:_startRunCallbacks 
--- <exception caught here> --- 
/usr/lib/python2.7/site-packages/twisted/internet/defer.py:551:_runCallbacks 
main.py:70:on_connect_success 
main.py:32:start 
main.py:49:handle_stop_signal 
/usr/lib/python2.7/site-packages/twisted/internet/base.py:577:stop 
] 

所以反应器被停止了,但它并没有退出程序。我必须键盘中断两次。一旦停止反应堆,并第二次抛出错误。有没有一种方法来设置这样的循环?

回答

8

反应器处理sigint,sigterm本身(可能有一个参数reactor.run(),禁用它)。改为安装reactor.addSystemEventTrigger('before', 'shutdown', client.disconnect)

参见twisted: catch keyboardinterrupt and shutdown properly

+2

只是想补充说,它是*不安全*调用信号处理程序内的扭曲的API。信号处理程序是抢占式上下文切换的一种形式,它们与线程一样不安全,必须小心处理。只有标记为线程安全的Twisted API可以用于信号处理程序(最有趣的是'reactor.callFromThread')。 –

+0

完美地工作,非常感谢! – mrobinson7627