Tornado で ブロッキング処理をノンブロッキング処理化する

Overview

Tornadoを使って
非同期処理を作るときには、対象のサービスを非同期化する必要がある。

その方法はいくつか方法があるが、最も最初に記載されているのが
@tornado.gen.coroutine を使う方法だ。

これにを使うことで、重たい処理をしていても次の処理を受け付けられるようになるということだが
例として記載されている方法は、tornadoに組み込まれている非同期処理ライブラリを使っている。
従って、外部コマンドを呼び出すなど、完全独自でブロッキング処理が入っている場合はどうすれば良いのか良く分からない。

そのための解が分かったので記載する。

http://www.tornadoweb.org/en/stable/faq.html

具体的には3.を使うことになるが、丁寧にもloopを書いてしまっているので混乱しがちだった。
従って、単純にこうすれば良い、という例を書いておく。

単純な例

基本形は以下の通り。

import tornado.concorrent
import time

@gen.coroutine
def run(time):
    yield executor.submit(time.sleep, time)
    return 

time.sleep を呼び出す関数に置き換える。
つまりこういう感じ。

import tornado.concorrent
import time

def long_time_func(time)
    time.sleep(time) # 重たい処理
    result = time    # とりあえずreturn value を定義
    return result

@gen.coroutine
def run(time):
    yield executor.submit(long_time_func, time)
    return 

とまあ、こんな感じ。
後は、 yield で run()を呼び出してやれば良い。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.