2012-01-22 9 views
1

から私はいくつかのリモートメソッドを呼び出すためにツイストPerspectiveBrokerを使用する必要があるWSGIアプリケーションを書いています。問題は、wsgiはレンダリングされたWebページを返す必要がありますが、Twistedサービスの呼び出しは非同期であることです。だから、基本的に私のWebアプリケーションは、リモートメソッドを呼び出す必要がありますし、いくつかの他のものをし、リモート呼び出しが完了するのを待たなければならないし、ページをレンダリングし、クライアントに返します。ツイストPerspectiveBroker callRemoteはWSGI Webアプリケーション

これを行うにはどのような方法が最適ですか?

私は現在、Flaskを使ってアプリを書く予定です。

答えて

4

WSGIアプリケーションは独自のスレッド(またはプロセス)で実行されます。 TwistedのWSGIコンテナで実行している場合、それは原子炉が動作しているスレッドとは異なるスレッドです。TwistedのAPIのほとんどはスレッドセーフではありません。リアスティックスレッドでのみ呼び出すことができます。

だから、スレッドセーフであるとreactor.callFromThreadを使用しているWSGIアプリケーションからツイストAPIを呼び出すための基本的な方法は、関数は原子炉のスレッドで呼び出されます。しかし

... 
reactor.callFromThread(pbRemote.callRemote, "someMethod", some, args) 

、これをあなたはおそらくあなたが望む結果を破棄します。あまりにも、それをしかし、結果を保存しreactor.callFromThreadの上にAPIを構築するためにシンプルだし、ツイストのそれの実装があります:

from twisted.internet.threads import blockingCallFromThread 

... 
result = blockingCallFromThread(reactor, pbRemote.callRemote, "someMethod", some, args) 

callRemote火災によって返された繰延まで、この呼び出しはブロックされますし、それがしますそのDeferredの結果を返します。

電話をかけたい場合は、他の仕事をしてから、電話が終了するのを待ってから少し創造しなければなりません。

resultHolder = blockingCallFromThread(
    reactor, lambda: [pbRemote.callRemote("someMethod", some, args)]) 

そして、あなたはあなたがする必要がある他のどのような作業を行うことができます:あなたが電話をかけると、それが返されますが、それをブロックしていないDeferred実際に取得する必要があります。あなたはPB呼び出しの結果を待つ準備ができたらと:

result = blockingCallFromThread(reactor, lambda: resultHolder[0]) 

これは、シングルスレッドのシナリオでツイストを使用するよりも、すべてではなく、より厄介であるので、確かにツイストウェブのネイティブを使用する方が簡単な場合がありWSGIアプリケーションを構築するのではなく、 WSGIの主な目標の1つは、Twisted、Apacheなど、さまざまなサーバー間で移植可能なアプリケーションを開発できるようにすることです。WSGIアプリケーションで実際にTwisted APIを使用している場合は、移植性がまったくありません。

1

server.NOT_DONE_YETを返して、twisted.webに要求が完了していないことを伝えることができます。そして、例えば、後で要求を完了するためにrequest.write()とrequest.finish()を呼び出します。

from twisted.web import server, resource 

class MyResource(resource.Resource): 
    def render_GET(self, request): 
     # the call will return defer, that will notify us when it finish 
     d = delayCall() 
     # finish the request 
     def finisn_req(data): 
      request.write(data) 
      request.finish() 
     d.addCallback(finisn_req) 
     # tell twisted.web that this request is not finished, yet 
     return server.NOT_DONE_YET 
+0

Twisted webを使うのがもっと簡単でない限り、私はFlaskを使ってwebappを書くつもりです。 – Blubber

+0

次に、ブローカーの作成、Twistedを使用したXML-RPCの受け入れ、サーバーへの呼び出しについて説明します。 Flask - > XML-RPC Broker - >あなたのサーバー? –