如何优雅退出应用程序开始扭曲?

时间:2011-03-17 19:23:35

标签: python twisted twisted.words twisted.application

我有一个jabber客户端正在读取它的stdin并发布PubSub消息。如果我在stdin上获得EOF,我想终止客户端。

我首先尝试sys.exit(),但这会导致异常而客户端不会退出。然后我做了一些搜索,发现我应该拨打reactor.stop(),但我无法完成这项工作。我的客户端中的以下代码:

from twisted.internet import reactor
reactor.stop()

exceptions.AttributeError: 'module' object has no attribute 'stop'

中的结果

我需要做些什么才能导致扭曲关闭我的应用程序并退出?

编辑2

最初的问题是由于某些符号链接导致模块导入混乱。解决了这个问题后,我得到了一个新的例外:

twisted.internet.error.ReactorNotRunning: Can't stop reactor that isn't running.

异常后,twistd关闭。我认为这可能是由于MyClient.loop中对MyClient.connectionInitialized的调用造成的。也许我需要将电话推迟到以后?

修改

这是我的客户端的.tac文件

import sys

from twisted.application import service
from twisted.words.protocols.jabber.jid import JID

from myApp.clients import MyClient

clientJID = JID('client@example.com')
serverJID = JID('pubsub.example.com')
password = 'secret'

application = service.Application('XMPP client')
xmppClient = client.XMPPClient(clientJID, password)
xmppClient.logTraffic = True
xmppClient.setServiceParent(application)

handler = MyClient(clientJID, serverJID, sys.stdin)
handler.setHandlerParent(xmppClient)

我正在使用

进行调用
twistd -noy sentry/myclient.tac < input.txt

以下是MyClient的代码:

import os
import sys
import time
from datetime import datetime

from wokkel.pubsub import PubSubClient

class MyClient(PubSubClient):
    def __init__(self, entity, server, file, sender=None):
        self.entity = entity
        self.server = server
        self.sender = sender
        self.file = file

    def loop(self):
        while True:
            line = self.file.readline()
            if line:
                print line
            else:
                from twisted.internet import reactor
                reactor.stop()

    def connectionInitialized(self):
        self.loop()

3 个答案:

答案 0 :(得分:7)

from twisted.internet import reactor
reactor.stop()
应该工作。事实上,这并不意味着您的应用程序出现了其他问题。我无法弄清楚你提供的信息有什么不妥。

你能提供更多(全部)代码吗?


编辑:

好的,现在的问题是你没有停止自己的while True循环,所以它会继续循环并最终再次停止反应堆。

试试这个:

from twisted.internet import reactor
reactor.stop()
return

现在,我怀疑你的循环对于事件驱动的框架来说不是一件好事。虽然你只是打印线条,但这很好,但是根据你想要做的事情(我怀疑你做的不仅仅是打印线条),你必须重构那个循环来处理事件。

答案 1 :(得分:5)

使用reactor.callFromThread(reactor.stop)代替reactor.stop。这应该可以解决问题。

答案 2 :(得分:1)

我曾经这样做过(在非扭曲调用的应用程序的sigint处理程序中):

reactor.removeAll()
reactor.iterate()
reactor.stop()

我不是100%肯定这是正确的方式,但扭曲很快乐

在tac中启动的相同应用程序是由扭曲信号处理程序直接处理的,我发现了这个问题,因为我有一些rpc客户端请求,我会等待并在退出之前处理结果,看起来像twistd只是杀死了反应堆没有让电话完成