2012-11-20 78 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