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

| | Comments (0) | TrackBacks (0)

何を作っていたかについて復習しておきましょう。

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

という感じのものを作っている途中でした。

そして、構成要素に分けると、

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

となるのでした。

前回は、

1から100までを一秒に1ずつカウントアップするworker
まで作ったのでしたね。

さっそく続きをはじめましょう。


Railsの準備


ここまでRailsのサーバーを起動していませんでしたので、Railsのサーバーの起動について念のため触れておきますね。

Railsのサーバーの起動は、script/serverを利用します。
(RAILSROOT)で、以下のようにします。
$ ./script/server
=> Booting Mongrel (use 'script/server webrick' to force WEBrick)
=> Rails application starting on http://0.0.0.0:3000
=> Call with -d to detach
=> Ctrl-C to shutdown server
** Starting Mongrel listening at 0.0.0.0:3000
** Starting Rails with development environment...
** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no restart).
** Rails signals registered.  HUP => reload (without restart).  It might not work well.
** Mongrel 1.1.3 available at 0.0.0.0:3000
** Use CTRL-C to stop.

「-d」を付けることで、デーモンプロセスとして起動することができますが、ログは有効なデバッグ手段の一つなので、専用のウィンドウを一つ立ち上げ、その中で起動すると良いでしょう。Ctrl-Cで停止させることができます。

上記の状態で、http://localhost:3000/でRailsにアクセスすることができます。

次に、レイアウトを設置しましょう。

レイアウトは、各ページに共通の要素をまとめて定義するための機能です。必須ではありませんが、HTMLを書く量が減るので、原稿の都合上利用させていただきます(笑)

以下の内容を、(RAILSROOT)/app/views/layouts/application.html.erbとして保存してください。

<html>
<head>
<title>brdbtest1</title>
<%= javascript_include_tag :defaults %>
</head>
<body>
<%= yield %>
</body>
</html>
</pre></div>


そのworkerをキックするページA

「スタート」をクリック→workerメソッドcount_upが起動する

というような流れを実装しましょう。

controllerの名前はcountupとします。

$ ./script/generate controller countup index
      exists  app/controllers/      exists  app/helpers/
      create  app/views/countup
      exists  test/functional/
      create  app/controllers/countup_controller.rb
      create  test/functional/countup_controller_test.rb
      create  app/helpers/countup_helper.rb
      create  app/views/countup/index.html.erb


この時点で、http://localhost:3000/countup/を見に行くと、以下のような画面が表示されるはずです。

bdrbtest1_3_001.png

まず「『スタート』をクリック」の部分を用意します。せっかくなのでRailsのAjax機能を使ってみましょう。

app/views/countup/index.html.erbを以下のようにしましょう。

<%= link_to_remote "Start", :url => { :action => 'start' } %>


次に「workerメソッドcount_upが起動する」に相当するアクション「start」を用意します。

app/controllers/countup_controller.rbを以下のようにしましょう。

class CountupController < ApplicationController

  def index
  end

  def start
    MiddleMan.ask_work(:worker => :foo_worker, :worker_method => :count_up)
    render :update do |page|
      page.alert "Asked worker to count up"
    end                                
  end                  
end       


MiddleMan.ask_workは、前回見た書式そのものですね。FooWorkerにcount_upメソッドを実行するようにお願いするメソッドでした。

本題から少し逸れますが、render :update以下は、元のページにJavaScriptアラートで反応を返すことを目的とした記述です。このstartアクションは、link_to_remoteタグによって、ブラウザからはxmlHttpRequestで呼び出されています。render :updateを使うことで、ブラウザには以下のような応答が返ります。Content-Type: text/javascriptだからJavaScriptとして実行されるという仕組みですね。

HTTP/1.1 200 OK
Connection: close
Date: Thu, 21 Feb 2008 05:29:21 GMT
Set-Cookie: _bdrbtest1_session=BAh7BiIKZmxhc2hJQzonQWN0aW9uQ29udHJvbGxlcjo6Rmxhc2g6OkZsYXNo%250ASGFzaHsABjoKQHVzZWR7AA%253D%253D--595f473532320fd4d049e91c14229afbcee7892d; path=/
Status: 200 OK
X-Runtime: 0.01252
ETag: "71d00b270c71787898354c71bfe1243a"
Cache-Control: private, max-age=0, must-revalidate
Server: Mongrel 1.1.3
Content-Type: text/javascript; charset=utf-8
Content-Length: 151

try {
alert("Asked worker to count up");
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('alert(\"Asked worker to count up\");'); throw e }Connection closed by foreign host.


こうした書式をRJS (Ruby-generated JavaScript)というそうです。これでJavaScriptを一行も書かずに済む...!ということには決してなりませんが、一部簡単に書くことはできそうですね。


さて、早速実際に見てみましょう。

http://localhost:3000/countup/を開くと、以下のような画面になっているはずです。

bdrbtest1_3_002.png

"Start"をクリックすると、以下のようなJavaScriptアラートが上がります。

bdrbtest1_3_003.png

FooWorkerにはask_workしたきり、結果を何も表示していないので、ブラウザには何も出ていませんが、うまくいっていればこの時点でcount_upがはじまっているはずです。
さっそくscript/console経由で見てみましょう。

$ ./script/console
Loading development environment (Rails 2.0.2)
>> MiddleMan.ask_status(:worker => :foo_worker)
=> 6
>> MiddleMan.ask_status(:worker => :foo_worker)
=> 7
>> MiddleMan.ask_status(:worker => :foo_worker)
=> 8


無事にworkerメソッドが呼ばれ、カウントアップされているのがわかると思います。

後はこのカウントアップから進捗グラフを作るだけですね。

では続きは次回!

0 TrackBacks

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

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

Leave a comment

About this Entry

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

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

例えば文章をめっちゃいい加減に要約してみる is the next entry in this blog.

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