主にプログラミングに関して。Python, .NET Framework(C#), JavaScript, その他いくらか。
記事にあるサンプルやコードは要検証。使用に際しては責任を負いかねます

スポンサーサイト

                
tags:
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Python-Tornado-Motor: gen.coroutineでコールバック関数を書かない

                
 TornadoはPythonのノンブロッキングIOが特徴なWebフレーム―ワーク。イマドキWebアプリ作るならたいていデータベースを使う。で、データベースってサーバ立てて使うからクエリを飛ばしてレスポンスが返ってくるまで、従来のWebフレームワークでならレスポンスのIO処理完了を待つ。レスポンスのIO処理完了待ちのあいだは割とCPUの負荷が軽かったりして、ほかのことをやることもできる。そこでノンブロッキングなWebフレームワークの場合は、IO処理の完了を待たずに次以降の処理を実行し、IOが完了したら戻ってその処理を再開する。そんなことをするため、データベースを使う時などは従来のフレームワークと違って、コールバック関数を使って書かなければならなかった。
http://www.tornadoweb.org/en/stable/gen.html

 Tornadoの開発が進んで、gen.coroutineなるデコレータが使えるようになり、最近はコールバック関数を書く必要がなくなった。
http://www.tornadoweb.org/en/stable/gen.html#other-classes

gen.coroutineの使い方は、コールバック関数抜きで書きたい関数(あるいはメソッド)にデコレータとして適用するだけ。あとはIO処理をする部分にyieldを付ければOK。return使いたければraise tornado.gen.Returnメソッドを使う。
class BaseHandler(tornado.web.RequestHandler):
@tornado.gen.coroutine
def get(self):
id_ = yield self.get_user_id("id")
self.write(id_)

@tornado.gen.coroutine
def get_user_id(self, s_id):
doc = yield db.session.find_one({"_id":ObjectId(s_id)})
if doc:
raise tornado.gen.Return(doc["user"])
else:
self.clear_cookie("s")
raise tornado.web.HTTPError(401)


 その他Motorを使う上で気に留めておく点。複数件データを取得したい場合、件数が決まっているならto_listメソッドを使う。カーソルを使ってループを回す手もあるが、それだとデータベースへのアクセスを複数回繰り返すことになる。それよりto_listメソッドで一度にまとめたほうが効率がいい。
docs = yield db.foo.find().to_list(length=5) # lengthで最大取得件数を指定するのは必須
            

コメントの投稿

非公開コメント

プロフィール

hMatoba

Author:hMatoba
Github

最新記事
リンク
作ったものなど
月別アーカイブ
カテゴリ
タグリスト

検索フォーム
Amazon
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。