问题
I am still very new to Python, but I have a grasp on the basics. I am trying to write a script that will allow me to interface with Deluge's API. Right now I am just trying to get the current download queue back, but the reactor keeps running. If I put reactor.stop() at the end of Deluge().onGetSessionState() then the reactor stops before Deluge().onGetTorrentStatus() comes back.
I'm confused on how to handle stopping the reactor when onGetSessionState gets everything it needs from onGetTorrentStatus.
from deluge.ui.client import client
from twisted.internet import reactor
class Deluge(object):
def __init__(self,*args):
for key, value in enumerate(args):
self.key = value
def getDownloadQueue(self):
self.connect("getQueue")
def connect(self,params):
deluge = client.connect()
deluge.addCallback(self.onConnect,params).addErrback(self.onConnectFail).addBoth(self.disconnect)
reactor.run()
def disconnect(self):
client.disconnect()
reactor.stop()
def onConnect(self,result,params):
def onGetTorrentStatus(torrentInfo):
print torrentInfo["name"] + " " + torrentInfo["label"]
def onGetSessionState(torrent_ids):
# This prints the torrent_ids just fine
print torrent_ids
# This only works if I keep the self.disconnect() below commented out
for id in torrent_ids:
client.core.get_torrent_status(id, ["name","label"]).addCallback(onGetTorrentStatus)
if params == "getQueue":
client.core.get_session_state().addCallback(onGetSessionState)
# self.disconnect()
def onConnectFail(self,result):
print "Error: %s" % result
reactor.stop()
deluge = Deluge()
deluge.getDownloadQueue()
回答1:
The specific issue you're hitting is that onGetTorrentStatus
is added as a callback to multiple Deferreds (because it is added inside the loop over torrent_ids
).
As soon as the first get_torrent_status
Deferred gets a result, onGetTorrentStatus
is called. If onGetTorrentStatus
stops the reactor then none of the other status calls get a chance to complete.
You want to wait for all of the get_torrent_status
Deferreds to get their results before stopping.
twisted.internet.defer.gatherResults
should help you with this.
You probably also want to look at twisted.internet.task.react
which will replace your calls to both reactor.run
and reactor.stop
(you still need gatherResults
though, or react
won't know the correct time to call reactor.stop
either).
回答2:
You can avoid the multiple Deferreds issue and simplify your script by calling client.core.get_torrents_status
and it will return all the current torrent id's in session and the specified status keys.
来源:https://stackoverflow.com/questions/21346498/how-to-properly-stop-twisted-reactor-when-callback-is-finished