So I’m writing a small script to use with Deluge. Deluge uses Twisted, and I really don’t have a firm grasp on how it works. Normally I’d just look up more info on it, but getting started with Twisted would take a long time and is beyond the scope of this little project. So I figured I would just ask here.
Now, I have this code. I’ll try to explain the specifig parts I need help with
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()
When a torrent is successfully added, it should go back to start(), and it does, but I think it loses the reactor or something. Because now whenever it recieves a SIGTERM or SIGINT, the reactor closes, but doesn’t quit the program:
± % 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 the reactor gets stopped, but it doesn’t quit the program. I have to keyboard interrupt twice. Once to stop the reactor, and a second time to throw the error. Is there a certain way to set up a loop like this?
reactor handles sigint, sigterm itself (there might be a parameter of
reactor.run() that disables that). Install
reactor.addSystemEventTrigger('before', 'shutdown', client.disconnect) instead.
See twisted: catch keyboardinterrupt and shutdown properly.