如何在回调完成时正确停止Twisted reactor

时间:2014-01-25 04:11:05

标签: python twisted

我仍然是Python的新手,但我掌握了基础知识。我正在尝试编写一个脚本,允许我与Deluge的API接口。现在我只是想让当前的下载队列恢复,但反应堆一直在运行。如果我将reactor.stop()放在Deluge()。onGetSessionState()的末尾,那么反应器会在Deluge()之前停止。onGetTorrentStatus()会回来。

当onGetSessionState从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()

2 个答案:

答案 0 :(得分:3)

您遇到的具体问题是onGetTorrentStatus被添加为多个Deferred的回调(因为它是在torrent_ids的循环内添加的。)

只要第一个get_torrent_status延期获得结果,就会调用onGetTorrentStatus。如果onGetTorrentStatus停止了反应堆,那么其他状态调用都没有机会完成。

您希望等待get_torrent_status延迟的所有在停止前获得结果。

twisted.internet.defer.gatherResults可以帮助您解决此问题。

您可能还想查看twisted.internet.task.react,它会取代您对 reactor.runreactor.stop的调用(尽管您仍然需要gatherResults ,或react也不知道拨打reactor.stop的正确时间。

答案 1 :(得分:0)

您可以通过调用client.core.get_torrents_status来避免多个Deferreds问题并简化脚本,它将返回会话中所有当前的torrent ID和指定的状态键。