Python Twisted deferToThread函数未按预期工作

时间:2011-11-26 16:33:31

标签: python twisted

我的目标是创建一个简单的服务器来处理TCP消息,例如“process My String”,它发送“My String”以通过称为(这里的slowFunction)的相当时间的操作来处理。这里我通过deferToThread调用这个函数但似乎没有发生任何事情:deferred的回调消息没有出现在任何地方(断点显示它从未被调用)并且函数中的print没有显示(断点显示它从未被调用)< / p>

from twisted import protocols
from twisted.protocols import basic
from twisted.internet import threads, protocol, reactor
from twisted.application import service, internet
import re
import time

def slowFunction(arg):
    print "starting process"
    time.sleep(1)
    print "processed "+arg

class MySimpleServer(basic.LineReceiver):

    PROCESS_COMMAND = "process (.*)" #re pattern
    processFunction = slowFunction
    clients = []

    def connectionMade(self):
        print "Client connected"
        MySimpleServer.clients.append(self)

    def connectionLost(self, reason):
        print "Client gone"
        MySimpleServer.clients.remove(self)

    def onProcessDone(self):
        self.message("Process done")

    def onError(self):
        self.message("Process fail with error")

    def lineReceived(self, line):
        processArgumentResult = re.search(MySimpleServer.PROCESS_COMMAND, line)
        if not processArgumentResult == None:
            processArgument = processArgumentResult.groups()[0] 
            deferred = threads.deferToThread(MySimpleServer.processFunction, processArgument)
            deferred.addCallback(self.onProcessDone)
            deferred.addErrback(self.onError)
            self.message("processing your request")
        else:
            print "Unknown message line: "+line

    def message(self, message):
        self.transport.write(message + '\n')

if __name__ == '__main__':
    factory = protocol.ServerFactory()
    factory.protocol = MySimpleServer
    factory.client = []

    reactor.listenTCP(8000, factory)
    reactor.run()

2 个答案:

答案 0 :(得分:3)

我得到了twisted irc

的帮助

要点是:回调(onProcessDone和onError)应该采用结果参数,deferToThread调用的函数将接收self作为参数(它应该是MySimpleServer类的方法之一)。

最终的代码现在是:

from twisted import protocols
from twisted.protocols import basic
from twisted.internet import threads, protocol, reactor
from twisted.application import service, internet
import re
import time

def slowFunction(arg):
    print "starting process"
    time.sleep(20)
    print "processed "+arg

class MySimpleServer(basic.LineReceiver):

    PROCESS_COMMAND = "process (.*)" #re pattern
    clients = []

    def connectionMade(self):
        print "Client connected"
        MySimpleServer.clients.append(self)

    def connectionLost(self, reason):
        print "Client gone"
        MySimpleServer.clients.remove(self)

    def onProcessDone(self, result):
        self.message("Process done")

    def onError(self, result):
        self.message("Process fail with error")

    def processFunction(self, processArgument):
        slowFunction(processArgument)

    def lineReceived(self, line):
        processArgumentResult = re.search(MySimpleServer.PROCESS_COMMAND, line)
        if not processArgumentResult == None:
            processArgument = processArgumentResult.groups()[0] 
            deferred = threads.deferToThread(self.processFunction, processArgument)
            deferred.addCallback(self.onProcessDone)
            deferred.addErrback(self.onError)
            self.message("processing your request")
        else:
            print "Unknown message line: "+line

    def message(self, message):
        self.transport.write(message + '\n')

if __name__ == '__main__':
    factory = protocol.ServerFactory()
    factory.protocol = MySimpleServer
    factory.client = []

    reactor.listenTCP(8000, factory)
    reactor.run()

答案 1 :(得分:3)

另一种可以做到这一点的方法是使用staticmethod;这是合法使用它。

class MySimpleServer(basic.LineReceiver):
    processFunction = staticmethod(slowFunction)