BackgrounDRb 1.0 (2) : Railsの背後でジョブを動かす

| | Comments (0) | TrackBacks (0)

 BackgrounDRbには、原作者が書いたわかりやすいチュートリアル"Introduction to BackgrounDRb"が存在しており、BackgrounDRbで検索するとこのページの内容を実践されている方のブログなどがヒットするのですが、残念ながらBackgrounDRb 1.0では仕様が大きく変わっており、このチュートリアルは動作しません。

 そこで、BackgrounDRb 1.0で上記のチュートリアルと似たようなことを実現してみたいと思います。

 イメージとしては、ボタンを押すと動画の変換処理がスタートして、状態表示ページにアクセスすると、変換処理が何%終了したかを表示する、そんなアプリケーションを作りたいのですが、動画の変換とかを本当に実装するのは時間の制約上難しいので、ここでは単に終了までに100秒かかるworkerを実装しましょう。

「スタート」を押す→処理がはじまる→処理の進捗状況がグラフ表示される

という感じのものを作りたいと思います。

構成要素に分けると、

  • 1から100までを一秒に1ずつカウントアップするworker
  • そのworkerをキックするページA
  • そのworkerの進捗状況をJSONかRJSで返すページB
  • Bを定期的に呼び出し進捗グラフを表示するAjaxなページC
となります。

退屈な順に、workerからいってみましょう!


1から100までを一秒に1ずつ数え上げるworker

 良い名前が浮かびませんので、チュートリアルに倣ってFooWorkerと名付けましょう。BackgrounDRbにはworkerのジェネレータがついていますので、generateコマンドでworkerのテンプレートを生成することができます。

$ ./script/generate worker foo 
      exists  lib/workers/
      create  lib/workers/foo_worker.rb


では、生成されたlib/workers/foo_worker.rbを見てみましょう。


class FooWorker < BackgrounDRb::MetaWorker
  set_worker_name :foo_worker
  def create(args = nil)
    # this method is called, when worker is loaded for the first time
  end
end


 非常にシンプルですね。

 さて、復習すると、1から100までを1秒に1ずつ数え上げるworkerを実装するのでした。

 1から100までの数字を保持するのインスタンス変数を定義して、その変数のgetterを...と考えてしまうところなのですが、BackgrounDRbには、statusという概念があります。statusは、(おそらく)workerの「現状」をMiddleManに受け渡すことを想定して作られており、Rails側からはMiddleManを通して簡単にstatusにアクセスすることができます。せっかくなのでここはこのstatusを利用してみましょう。

 statusに値を「登録」するには、register_statusメソッドを利用します。今回は、このregister_statusを利用してみましょう。以下のようになります。数え上げるメソッドを、count_upとしました。

lib/workers/foo_worker.rb

class FooWorker < BackgrounDRb::MetaWorker
  set_worker_name :foo_worker
  def create(args = nil)
    # this method is called, when worker is loaded for the first time
  end
  def count_up
    (1..100).each { |i| 
      register_status(i)
      sleep 1         
    } 
  end       
end


 ではこれを手動で呼び出してみましょう。

前回見た手順で、backgroundrbのサーバーを起動します。

$ ./script/backgroundrb start

次に、Railsのコンソールを起動します。ここにコマンドを打ち込んで手動でworkerの機能を呼び出しましょう。

$ ./script/console
Loading development environment (Rails 2.0.2)
>> MiddleMan.query_all_workers
=> {:foo_worker=>nil, :log_worker=>nil}

FooWorkerはbackgroundrbの起動時に読み込まれ、インスタンスが存在しているようです。

>> MiddleMan.ask_work(:worker => :foo_worker, :worker_method => :count_up)
=> nil


 これでworkerのメソッドcount_upが呼び出されたはずです。続けて、statusを取得してみてください(急いで!)。

>> MiddleMan.ask_status(:worker => :foo_worker)
=> 11
>> MiddleMan.ask_status(:worker => :foo_worker)
=> 12
>> MiddleMan.ask_status(:worker => :foo_worker)
=> 13


一秒ごとに、statusがカウントアップされているのがわかりますね。
しばらく待ってから実行すると、

>> MiddleMan.ask_status(:worker => :foo_worker)
=> 100

...こんな感じでカウントアップが終了していることがわかります。

一目瞭然ではありますが、MiddleMan.ask_workは、特定のworkerにあるメソッドの実行をお願いするメソッドです。MiddleMan.ask_statusは、workerが登録したstatusを取得するメソッドです。

 これでworkerはとりあえず完成です!あとはこのworkerをRailsから呼び出せば良いわけです。開始するページはMiddleMan.ask_workを呼び出し、進捗を返すページはMiddleMan.ask_statusを呼び出せば良さそうですね。

では続きはまた次回。(中断する場合には./script/backgroundrb stopをお忘れなく)

0 TrackBacks

Listed below are links to blogs that reference this entry: BackgrounDRb 1.0 (2) : Railsの背後でジョブを動かす.

TrackBack URL for this entry: http://lab.hde.co.jp/blog/mt-tb.cgi/21

Leave a comment

About this Entry

This page contains a single entry by rgoura published on February 21, 2008 12:00 PM.

BackgrounDRb 1.0 (1) : Railsの背後でジョブを動かす was the previous entry in this blog.

BackgrounDRb 1.0 (3) : Railsの背後でジョブを動かす is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.