2012-11-20 4 views
6

Also schreibe ich ein kleines Skript, um mit Deluge zu verwenden. Deluge benutzt Twisted, und ich habe wirklich keinen festen Überblick darüber, wie es funktioniert. Normalerweise würde ich nur mehr Informationen darüber suchen, aber mit Twisted anzufangen würde eine lange Zeit nehmen und ist außerhalb des Umfangs dieses kleinen Projekts. Also dachte ich, ich würde einfach hier fragen.Twisted Reaktor ist gestoppt, aber Programm endet nicht?

Jetzt habe ich diesen Code. Ich werde versuchen, die specifig Teile ich helfen mit

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() 

müssen zu erklären, wenn ein Strom erfolgreich hinzugefügt wird, sollte es zurückgehen() zu starten, und es funktioniert, aber ich denke, dass es in den Reaktor oder etwas verliert. Denn jetzt, wenn es einen SIGTERM oder SIGINT recieves, der Reaktor geschlossen, aber nicht beendet das Programm:

± % 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 
] 

So ist der Reaktor gestoppt wird, aber es ist nicht das Programm beenden. Ich muss die Tastatur zweimal unterbrechen. Einmal, um den Reaktor zu stoppen, und ein zweites Mal, um den Fehler zu werfen. Gibt es einen bestimmten Weg, eine Schleife so einzurichten?

Antwort

8

reaktor handles sigint, signerm selbst (es könnte ein Parameter von reactor.run() sein, der das deaktiviert). Installieren Sie stattdessen reactor.addSystemEventTrigger('before', 'shutdown', client.disconnect).

Siehe twisted: catch keyboardinterrupt and shutdown properly.

+2

Ich möchte nur hinzufügen, dass es nicht sicher * Twisted APIs in einem Signal-Handler aufrufen. Signalhandler sind eine Form der präventiven Kontextumschaltung, sie sind genauso unsicher wie Threads und müssen sorgfältig behandelt werden. Nur Twisted-APIs, die als Thread-sicher gekennzeichnet sind, können in einem Signal-Handler verwendet werden (der interessanteste davon ist "reactor.callFromThread"). –

+0

Funktioniert perfekt, vielen Dank! – mrobinson7627

Verwandte Themen