2012-02-16 3 views
2

私のコードは次のようになります。ツイストノンブロッキング法 - どのように?

... # class Site(Resource) 
def render_POST(self,request) 
    otherclass.doAssync(request.args) 
    print '1' 
    return "done" #that returns the HTTP response, always the same. 

... 

def doAssync(self,msg): 
    d = defer.Deferred() 
    reactor.callLater(0,self.doStuff,d,msg) 
    d.addCallback(self.sucess) 

def doStuff(self,d,msg): 
    # do some stuff 
    time.sleep(2) #just for example 
    d.callback('ok') 

def sucess(msg): 
    print msg 

出力:

OK

、これまでのところ、とても良いが、HTTPレスポンス(復帰 " done ')、遅延の後にのみ発生します(time.sleep(2))。 ブラウザは2秒間「読み込み中」を保持するので、これを知ることができます。

私は間違っていますか?

+0

回答が見つかりました:http://stackoverflow.com/questions/6759115/asynchronous-wsgi-with-twisted – joaoricardo000

+2

Twisted APIを使用するスレッドについては、Deferreds、つまりd.callback-inを含めて、注意してください。このバージョンのコードは間違ったスレッドで 'd.callback'を使います。これにより、すべてのコールバックが間違ったスレッドで実行されてしまいます。結果を出力するだけではなく、何かを壊してしまうでしょう。 –

答えて

3

あなたが間違っているのは、ブロッキングコール(time.sleep(2))を実行していますが、Twistedはノンブロッキング操作のみを実行すると予想しています。待たないこと。あなたはそこにtime.sleep(2)を持っているので、その機能が寝ている間にTwistedは何もできません。したがって、ブラウザにもデータを送信することはできません。

time.sleep(2)の場合は、別のreactor.callLaterコールに置き換えます。実際にtime.sleep(2)呼び出しが他のブロック操作であると仮定した場合、それを修正する方法は操作によって異なります。ノンブロッキングな方法で操作を行うことができれば、それを行います。多くのそのような操作(データベースのやりとりのような)のために、Twistedにはすでに非ブロックの選択肢があります。もしあなたがやっていることが非ブロッキングインターフェースを持たず、Twistedにはそれに代わるものがないならば、別のスレッド(例えばtwisted.internet.threads.deferToThreadを使って)でコードを実行しなければならないかもしれませんが、 -安全。

+0

彼は 'reactor.callLater(...)'を 'deferToThread(...)'に置き換えることができますか? –

+0

はい、ちょうどこれを行い、私の問題を解決しました!ありがとう!! – joaoricardo000

+0

reactor.callInThread(global_function)を実行し、global_functionにローカルファイルを読み込み、その内容を処理するようなブロック操作がある場合。 global_functionが実行されている間は、応答が著しく遅くなるため、工場スレッドが影響を受けているように見えますが、その理由は分かりますか? –