How to properly stop Twisted reactor when callback is finished

回眸只為那壹抹淺笑 提交于 2020-01-24 13:21:07

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!