2013-10-29 18 views
6

私は通常、竜巻ベースのWebアプリケーションの一部として使用するtornado gen.coroutineを使用していくつかの非同期関数を使用しています。しかし、いくつかの管理作業を行うために、古いpythonスクリプトからそれらのいくつかを呼びたいと思います。これはどうすればいいですか?通常のPythonスクリプトでトルネード非同期コードを使用する

from tornado import gen 

import some_internal_stuff 

@gen.coroutine 
def myfunc(x): 
    y = yield some_internal_stuff.another_async_func(x) 
    raise gen.Return(y) 

if __name__ == "__main__": 
    # What do I put here to call myfunc(1) and get the async return value? 
    pass 

更新:

より具体的な例:

この出力を実行する
from tornado import gen 

@gen.coroutine 
def another_async_func(x): 
    print "aaf" 
    raise gen.Return(x + 1) 

@gen.coroutine 
def myfunc(x): 
    print "myfunc" 
    y = yield another_async_func(x) 
    print "back" 
    raise gen.Return(y) 

def callback(y): 
    print "Callback called with %d" % y 

if __name__ == "__main__": 
    myfunc(1, callback=callback) 

myfunc 
aaf 
+1

結果を待っていますか?あなたが呼び出す関数はこれを防ぐ竜巻に依存していますか? –

+0

@rod:アイデアは 'another_async_func'は、通常はトルネード' IOLoop'の存在下で動作する別の竜巻 '@ asynchronous'メソッドです。 'another_async_func'を実行して' callback'を渡すことはできますが、竜巻が走っていなければ、 'myfunc'のyield後の行は決して実行されず、渡されたコールバックは呼び出されません。 – rakslice

答えて

16

実行するIOLoopにおける組み込みメソッドrun_syncがあります1回の呼び出しとその後ループの上部にあるので、PYTHONPATHに竜巻があれば、単純なPythonスクリプトにイベントループを追加するのはかなり簡単です。

from tornado import gen, ioloop 

@gen.coroutine 
def another_async_func(x): 
    print "aaf" 
    raise gen.Return(x + 1) 

@gen.coroutine 
def myfunc(x): 
    print "myfunc" 
    y = yield another_async_func(x) 
    print "back" 
    raise gen.Return(y) 

@gen.coroutine 
def main(): 
    y = yield myfunc(1) 
    print "Callback called with %d" % y 

if __name__ == "__main__": 
    ioloop.IOLoop.instance().run_sync(main) 

この出力:具体的な例では

run_syncが良くない巣を行うこと

myfunc 
aaf 
back 
Callback called with 2 

注意。同じIOLooprun_syncという関数でrun_syncを呼び出すと、内部コールの完了によってIOLoopが中止され、内部コールが返された後でさらにyieldが終了します。ここで

1

は、問題の複雑さや、ニーズに応じて動作しますスレッドを使用して、別の可能性です:

直接、このような明白な質問をして申し訳ありませんが、何some_internal_stuff.another_async_func(X)を呼び出してからあなたを防ぐ
if __name__ == "__main__": 
    import threading, time 
    # The tornado IO loop doesn't need to be started in the main thread 
    # so let's start it in another thread: 
    t = threading.Thread(target=IOLoop.instance().start) 
    t.daemon = True 
    t.start() 

    myfunc(1, callback=callback) 
    # now the main loop needs wait; you can do that by polling a value, sleeping, 
    # or waiting on a lock. I've chosen to sleep here, but a lock is probably more 
    # appropriate; and, once computation is done, release the lock. 
    time.sleep(2) 
関連する問題