2

如何像在 Node.js 中一样在 Twisted 中进行异步请求处理?

我用 Twisted 编写了示例,但我的应用程序仍然等待长时间操作的答案(我用 time.sleep 模拟这个)。

另外我不明白如何正确使用 reactor.callLater。

这是我的扭曲应用程序示例。


from twisted.web import server
from twisted.web.resource import Resource
from twisted.internet import reactor
from twisted.internet.defer import Deferred
import time

class Hello(Resource):
    def getChild(self, name, request):
        if name == '':
            return self
        print name
        return Resource.getChild(self, name, request)

    def render_GET(self, req):
        d = Deferred()
        reactor.callLater(2, d.callback, None)
        d.addCallback(lambda _: self.say_hi(req))
        return server.NOT_DONE_YET

    def say_hi(self, req):
        req.setHeader("content-type", "text/html")
        time.sleep(5)
        req.write("hello!")
        req.finish()

class Hello2(Resource):
    isLeaf = True
    def render_GET(self, req):
        req.setHeader("content-type", "text/html")
        return "hello2!"

root = Hello()
root.putChild("2", Hello2())
reactor.listenTCP(8080, server.Site(root))
reactor.run()

编辑:现在的问题是如何编写同步代码?请举例。

4

1 回答 1

4

你已经在这样做了……有点。

您的问题是这time.sleep()是一个阻塞呼叫,因此会使您的整个服务器停止。

如果您将其用作执行网络 I/O(如urllib)的替代品,最好的选择通常是使用 Twisted(如twisted.web.client.getPage)进行 I/O,而不是尝试对阻塞代码做一些事情. Twisted 有很多客户端库。这些库通常会给你一个Deferred你已经在处理的。

如果您将它用作实际等待的替代品,那么您可以Deferred使用deferLater.

如果您将它用作不占用 GIL(如 PIL 图像编码或本机 XML 解析器)或现有本机/专有 I/O 层(如 Oracle 或 MSSQL)的 CPU 密集型的替代品数据库绑定),您不想重写以正确使用 Twisted,您可以使用deferToThread.

无论你得到什么Deferred,你几乎都准备好处理它了。你只需要调整say_hi返回一个:

def say_hi(self, req):
    req.setHeader("content-type", "text/html")
    d = getADeferredSomehow()
    def done(result):
        req.write("hello!")
        req.finish()
    return d.addBoth(done)
于 2011-11-16T21:06:57.727 回答