/ / 最新 / 2010-01 / RSS / twitter / tumblr / 09014502501 / mail@ssig33.com

高密度小池


Rails で非同期処理

1.何故非同期処理が必要か

Rails に限らず Web アプリケーション全体の話。クローラーとかバッチ系のものはとりあえず置いときます。
Web アプリケーションとはリクエストに対して処理を行ないレスポンスを行なうものですが、 1 リクエストにつき何個の処理があるというのはそれなりによくあることだと思います。仮にリクエストに対して 3 個の処理があったとします。
通常では、 3 個の処理が全て終ってからレスポンスを返すことになりますが、例えば処理 A B C がそれぞれあったとして、レスポンスには処理 A B の結果のみが記されていて C の結果はレスポンスには含まれないとします。
この時、処理 C が時間がかからず終わるものならば大した問題にはなりませんが、処理 C が極めて時間がかかるものだったとすると、全体のレスポンスが遅くなってしまいます。
であれば、処理 C を非同期化して、処理 C の終了を待たずにレスポンスを返した方がいいということになります。

2.Rails で非同期処理する方法

2-1.プラグインを使う
Rails 向けに非同期処理を簡単に実現する為のプラグインがいくつか用意されています。代表的なものとしては BackgrounDRb と AP4R あたりが上げられるんではないかと思います。これらにはそれぞれメリットとデメリットがあります。
2-1-1.BackgrounDRb
多分一番メジャーな奴。メリットとしては開発が活発に進んでいることと比較的各種の設定が簡単で導入しやすいこと。デメリットとしては開発が活発に進みすぎて API がどんどん変更され、どれが正しい最新の情報なのか分かりづらいことと、非同期処理の内容を変更した際にサーバーをいちいち再起動しないといけなくてあまりスピーディに開発を行なえない点が上げられます。
個人的にあまり好きじゃない。
2-1-2.AP4R
国産の非同期処理フレームワーク。たんなる非同期処理のプラグインというよりは非同期並列アプリケーションを作成する為のフレームワークという様相があるプラグインです。メリットとしては高可用性のあるアプリケーションを比較的簡単に構築できること、 Rails 以外の手段で作られたアプリケーションとも簡単に連携できること、高機能ではあるが単純な利用であれば簡単に導入できること、 Web の仕組みを最大限利用したものなので、 Rails のスピーディーな開発特性をそのまま生かせることが挙げられます。デメリットとしては古い gem に依存していることや、開発があまり活発ではないので設計が 2.x 時代の Rails からすると若干古くなっていることが挙げられます。

2-2.自前で小さいものを作る
以上二つのプラグインはそれぞれにメリットデメリットがありますが、共通するところとしてちょっとしたものを非同期化するのには大袈裟すぎるという点があります。
また特に BackgrounDRb ではテストが困難だったりします。
個人的には、ちょっとした非同期処理であれば自前で書いてしまった方がいいのではないかと思っています。

具体的には以下のようにしています。

1.text 型で :data というカラムを持った Async というモデルを作る。
2.アプリケーションから非同期になにかやりたい時は {:method => 処理の名称, :args => 引数} みたいな感じのハッシュを JSON 化して Async のインスタンスを create する
3.Async の中身を見て、何かあったら :method の処理に :args の引数を渡して走らせ、終ったら対象を destroy するというメソッドをどっかに作って cron で ./script/runner 経由で回す


このやり方であれば標準のテスト機構や RSpec で非同期処理の全てをちゃんとカヴァー出来るテストを特別な配慮無しに書けるんじゃないかと思う。

並列化したい場合はロックの為のカラムを Async に作って、メソッドを並列に回せばいいと思います。

3.まとめ
だらだらと適当に書いた感じですが、 Rails では非同期処理もとても簡単なので、やってみればいいんじゃないでしょうか。

blog comments powered by Disqus

Referrer (Inside):

[ 固定リンク ]