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 で I/O を行うのが最善の方法です ( など)。 twisted.web.client.getPage. Twisted には多くのクライアント ライブラリがあります。これらのライブラリは通常、Deferred既に処理している を提供します。

実際に待機するための代役として使用している場合は、Deferredで待機する を作成できますdeferLater

GIL (PIL 画像エンコーディングやネイティブ XML パーサーなど)、または既存のネイティブ/独自の I/O レイヤー (Oracle や MSSQL など) を取得しない CPU 集中型の代用として使用している場合Twisted を適切に使用するために書き換えたくないデータベース バインディングなど) は、 で呼び出すことができますdeferToThread

どのように を取得してDeferredも、それを処理する準備はほとんど整っています。say_hi1つを返すように調整する必要があります:

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 に答える