あまり、ネットで検索しても出てこないのでメモ。Railsのセッション(Cookie)はブラウザーが終了すると消えてしまう。で、ブラウザーが終了した後も残す方法だが、以前のRails(おそらく2.2以前)だと、environment.rbあたりに次のように書く。
ActionController::Base.session_options[:session_expires] = Time.local(2009, 1)
詳しくは以下のサイトにある。
sessionに有効期限を設定する時の試練 – ザリガニが見ていた…。
が、やってみても思ったようにいかず、ブラウザーを終了するとセッションも失われてしまう。いろいろとネットを検索してみたところ、次のページにたどりついた。
Active Record Session expiration in Rails 2.3 – Ruby on Rails: Talk | Google グループ
いわく、
Oh, I found the reason
:session_expires has been replaced by :expire_after.
とのこと。確認していないが、expire_afterてことは、最後にアクセスしてからの有効期間が指定出来るのだろうか?
(追記)↑出来るようです。リロードするたびにCookieのexpire日次が更新されてます。
以前、書いたようにRailsアプリの実行環境を作るのはいささか面倒だ。PHPアプリのようにサーバーにアップするだけでは動かず、ちょっと面倒である。
大徳日記 » Railsのアプリの実行環境について調べてみました
が、最近Passenger(mod_rails)なるものが出てきて話題になっているので試してみた。インストールに参考にしたのは次のページ。
Rails 2.0 » ホスティングサービスでもRailsが利用できるようになるかも、な「Passenger」
LoadModuleの設定などを書いておけばあとは簡単だ。仮想ホストのドキュメント・ルートがrailsアプリのpublicディレクトリーになっていればそれでOK。またサブディレクトリの場合も、
<virtualhost *:80>
ServerName www.phusion.nl
DocumentRoot /websites/phusion
RailsBaseURI /rails # This line has been added.
</virtualhost>
としておけばOKである。上の例では/railsがrailsアプリのpublicディレクトリーへのシンボリックリンクになっている。詳しくはマニュアルにある。
さてここで疑問に思ったのが、「じゃあ、仮想ホスト毎に1つのRailsアプリしかホスティングできないのか?」ということ。RailsBaseURIを2つ以上指定してもちゃんと動くのか実験してみた。hogeとpiyoという2つのRailsアプリを2つ作ってそれぞれx,yのサブディレクトリにリンク。apacheの設定は次の通り
RailsBaseURI /x/rails
RailsBaseURI /y/rails
さっそくブラウザーでアクセスしてみるとちゃんとどちらも動いていた。すかさず直前のエントリーのコメントでさいとさんに教えてもらった方法でruby1.8のプロセスを見てみる。
UID PID PPID C STIME TTY TIME CMD
root 11021 11020 0 16:51 ? 00:00:00 Passenger spawn server
root 20271 11021 3 22:23 ? 00:00:00 Passenger FrameworkSpawner: 2.0.2
daitoku 20272 20271 0 22:23 ? 00:00:00 Passenger ApplicationSpawner: /home/daitoku/work/hoge
daitoku 20274 1 0 22:23 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20281 20271 0 22:23 ? 00:00:00 Passenger ApplicationSpawner: /home/daitoku/work/piyo
daitoku 20283 1 0 22:23 ? 00:00:00 Rails: /home/daitoku/work/piyo
rootで動いている上の2つのプロセス(11021と20271)はトップレベルで各アプリ毎に振り分けるためのサーバーなのだろう。で、1レイヤー下に各アプリ毎に振り分けるサーバーがいてそれぞれhogeアプリが20272、piyoアプリが20281ぽい。で、実際にリクエストを処理するのが20274と20283なのではないだろうか?
ためしにabでhogeに対して5並列の負荷をかけてみると、案の定Rails:で始まるプロセスが増えている。1つ多く6プロセスなのは余分に1つ立ち上げているのだろう。
UID PID PPID C STIME TTY TIME CMD
root 11021 11020 0 16:51 ? 00:00:00 Passenger spawn server
root 20271 11021 0 22:23 ? 00:00:00 Passenger FrameworkSpawner: 2.0.2
daitoku 20412 20271 1 22:29 ? 00:00:00 Passenger ApplicationSpawner: /home/daitoku/work/hoge
daitoku 20414 1 12 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20418 1 5 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20421 1 7 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20423 1 1 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20425 1 3 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
daitoku 20434 1 21 22:29 ? 00:00:00 Rails: /home/daitoku/work/hoge
さらにこの状態で5並列でpiyoにも負荷をかけてみたら、別途piyoも6プロセス起動した。長くなるのでプロセス一覧は割愛するが、hogeのrubyプロセスはhogeの処理だけ、piyoのrubyプロセスはpiyoの処理だけ行うということが判明。うまくして1つのRailsプロセスがhogeもpiyoも処理できるようにするとすごいかも。
いやいやmod_rails便利です。
RESTful本でプレゼントが当たったからというわけではないが、RESTful読書会に参加してきました。本当はプレゼントのTシャツを着て行きたかったのだが風邪ぎみなので断念。が、私の他にもプレゼントをもらったt-wadaさんはばっちり着てきてました。さすがです。
今回の範囲は、1章、2章、3章だったがみんないろいろ熱い議論をしたくて集まっているだけあって1章からスパークしていました。以下、今回の収穫と感想。
また会場にはもちろんRESTに肯定的な人が多い中、その中でも客観的な分析をしていたkdmsnrさんの意見が興味深かったです。
残念ながら次回は仕事で参加できない予定。RESTは最近なにかと話題になっているもののまだまだで、これらどのように発展していくのかが楽しみです。
以前無邪気にもベータ版の本の間違いを見つけて送ったなどと書いたがよくよく見てみると間違えていたのは自分だったことが判明。お恥ずかしい限りです。しかもろくにコメントを読まずに引用しているし。
簡単に説明するとRails2.0からconfig/routes.rbに以下のようにルーティングを設定することにより
route.resources articles
RESTfulな思想に基づいて自動的にリソースarticleのCRUD処理が規約に従ってマッピングされる。で、このリソース(この場合はarticles)は通常複数形のところをこの本では特別に単数形で使われていたのだが、私は気付かずに「おいおい、新規のリソース作成は複数形のPOST /friendsでしょう」と書いたのだがこれは私の間違い。よく見てみるとちゃんと本にも前のページに
map.resource :session
Note that we’re using map.resource (singular) here, not plural as is usually the case. For a given user, we only need one session. The singular form generates routes and helpers using the singular name (session) as we’ll see in minute.
と書いてある。ちなみにsingular=単数形、plural=複数形です。しかも私の的外れなコメントに対して
Mike says:
Actually, it’s a singular resource (map.resource :session), so in the form tag you use the singular form.–Daitoku Saitou
と親切に書いてあった。嗚呼、穴があったら入りたいです…。
The Pragmatic Bookshelf | Advanced Rails Recipesなる本はまだ出版されていない。が、読むことができる。なぜなら私はベータ版の状態でPDFで購入しているからだ。このPDF版を買った人はいち早くベータ版の原稿を読むことができるし、紙の本も買うことが出来る。紙のバージョンの本は出版された後に配送されてくる。PDF版を買った人は最新版が読める上、間違いを見つけると投稿することも出来る。
今日、最新版のPDFが出来たよーというメールが来た。以前、間違いかと思ってErrataのページに投稿していたので早速見てみると、
Mike says:
Actually, it’s a singular resource (map.resource :session), so in the form tag you use the singular form.–Daitoku Saitou
なるコメントとともにちゃんと直っていた。ちょっと嬉しい。日本の出版界も取り入れればいいと思うんだけど、PDFの形式で出版前に代金をとって販売というのが日本の出版業界では何かの問題になっているのかも知れないですね。
rails 1.8.6以上が必要です。debianのstableは1.8.5なのでいったんrubyを全部抜いて
sudo apptitude purge ruby1.8
testingの(1.8.6)を入れます。
sudo aptitude install ruby1.8/testing
sudo aptitude install ruby1.8-dev/testing
sudo aptitude install rubygems/testing
sudo gem install thin
まだMongrelみたくクラスターを起動するような機能はないようなので、自作する必要があるようです。
そういえば前回のRails勉強会でRailsアプリを公開する際のノウハウを聞けると思って参加してみたものの詳しい人がおらず分からずじまい。ネットでいろいろと調べたので晒しておきます。間違いを見つけたら教えてください。
予備知識は以下の通り。
調べているうちに最初に気づいたことは「1つのRailsインスタンス(1つのRubyプロセス)が同時に処理できるHTTPリクエストは1つだけ」ということである。びっくりした。念のため2つのブラウザーを立ち上げて、長い間sleepするコントローラーにリクエストを投げると、もうひとつのブラウザーでは簡単なリクエストにもかかわらず1つめのブラウザーのsleepが終わるまで待たされたので間違いないようだ。The Futures of Ruby Threadingのささださんコメントにもあるが、RubyのVMではGlobal Interpreter Lock (GIL)を取得するので同時に動けるスレッドは1つだけだ。この制限は現行のRuby1.8からRuby1.9(YARV)になってユーザーレベルスレッド(グリーンスレッド)からカーネルスレッドになっても同じである。
As you know, YARV support native thread. It means that you can run each Ruby thread on each native thread concurrently.
It doesn’t mean that every Ruby thread runs in parallel. YARV has global VM lock (global interpreter lock) which only one running Ruby thread has. This decision maybe makes us happy because we can run most of the extensions written in C without any modifications.
では複数のリクエストを同時に処理したい場合はどうするのだろうか?これには複数のRubyプロセスをあらかじめ起動しておき複数のプロセスで処理することで対応する。1プロセス=1スレッドというわけだ。このあたりは1プロセス=複数スレッドというJavaの世界とは異なる。最初はいまどきプロセス単位で並列かよとも思ったが、よくよく考えてみたらWebアプリは並列して動かしてもお互いの処理は独立していてお互いに協調する必要はほとんどないのでプロセス単位の並列化でもいいのかも知れない。Rails2.0からセッションもCookieStoreになったし。で、複数プロセスを起動するための方法としては大きく分けて2つあり、仮にFastCGI方式とMongrel方式と呼ぶことにする。
まず比較的トラディショナルな方式がFastCGI方式だ。FastCGIはPerlなど別のLL言語でも使われる方式で、あらかじめ複数のRubyプロセスを常駐しておいてそれらをフロントのWebサーバーから呼び出す。Webサーバーとしては、Apacheだといろいろと問題があるらしくRailsの世界ではLIGHTtpd(通称Lightly)という軽量Webサーバーが使われるのが一般的なようだ。Webサーバーと常駐しているRubyプロセス間の通信はソケット通信で行う。LIGHTtpdは静的コンテンツも高速に処理できるためLIGHTtpd+FastCGIで完結し割とすっきりな構成となる。
もうひとつの方式が最近メジャーになりつつあるMongrel方式だ。これは、MongrelというWebサーバーを使って1ポート=1Mongrelサーバー=1Rubyプロセスで複数のMongrelサーバーを起動する。例えば5並列で処理したい場合、5つのMongrelサーバー(5つのRubyプロセス)を起動してポート番号50,000から50,004で待ち受けて処理する。ただMongrelサーバーの作者はRuby on Railsはゲットーだにあるように開発をやめようとしているので、ポストMongrel時代のWebサーバにあるように最近ではThinなど別のサーバーが注目されている。
Mongrel方式の場合、複数のポートで処理を待つので外部に公開する場合はMongrelだけでは不十分で、1つのポートで待ち受けてリクエストを複数のMongrelに分配するリバースプロキシー+ロードバランサーが必要になってくる。このロードバランサーにはいろいろとあって一番お手軽なのはApacheのモジュールのmod_proxy_balancerだ。他にもこの種のソフトにはPoundやSwiftiplyやnginxなどお腹いっぱいの充実ぶりだ。
結局どの方式にしてもそれなりに複雑であり、フロントとバックエンドの組み合わせとなると無限にある。この状況に対して、No True “mod_ruby” Is Damaging Ruby’s Viability On The Webなどで「だからなかなかRubyのブログや掲示板が流行らないんだ!」と問題提起されている。ちなみにこのページはRubyのWebアプリのトポロジーに複雑さにとどまらずスレッドの話などの議論も行われており興味深い。またこのページの作者による簡単にRubyアプリをデプロイをめざしてSwitchPipeなる試みもある。
さて気になるパフォーマンスはくまくまーの人のブログにクアッドコアでの測定結果がのっているが、これによると意外にLIGHTtpd+FastCGIが一番のようだ。またすでにApacheを動かしている場合はApache2 + mod_proxy_balancer + Mongrelが一番素直だと思った。
またApacheなどからバックエンドに飛ばす場合のURLのパスの書き換えはどうするの?問題についてはこれまたくまくまーの人のブログにある。このエントリーは面白いので最初から最後までじっくりと読むことをおすすめします。
でもこれら以外にまったく違う形式としてwarにしてJRubyアプリとしてJavaのアプリケーションサーバーにデプロイというのもあるそうですが、それはまだ調べ中なのでまたの機会に…。
前にSIM氏も絶賛していたし、昨日もAR氏もなかなかいいといっていたのでNetBeansを入れて試してみた。以下、メモ
SQLite3を使ってからというものすっかりサーバー起動が不要なファイル形式が好きになってしまった。もはやcreate dbもcreate tableも打たなくてもいいのはものぐさな私としては実に魅力的。100件ぐらいしか入っていない開発用DBにクラサバのリレーショナルDBなんて100年早いわっなどと思う。しかも勝手にSQLite3やDerbyって簡易的なDBだから相関副照会やOuter Joinって使えないと思っていたら問題なく使えるようだ。
さて肝心のIDEの機能だがちょっと触ってみた感じではEclipseっぽくコード補完もしてくれるしなかなかである。そのうちRails 2にも対応するでしょう。それにしても家の24インチのモニターでIDEが動いているのを初めて見たのだがとってもステキでした。
Ruby談義をということでNAIST時代のAR氏と新宿でタイ料理。確かザガットサーベイにも載っているピッチーファーというタイ料理店なのだがいつのまにか広い2号店が出来ておりその2号店で食事。その名もピッチーファー2th。英語がさほど得意でもない私でもそれって2ndの間違いでは?とつっこみたくなる。”2th”なる単語があるのかと思い検索してみたらこの店のページが1番上だった。うーん。
で、Rubyだけでなくいろいろとディープな話をしてたらあっという間に終電の時間。とても楽しかったです。それにしても2軒目に行ったドイツのビールの店は高かった。おいしかったけど。で、その店でドイツワインの赤というものをはじめて飲んだらなかなかだった。実は有名なのだろうか?
何かと話題な本なのでプチッとクリックして英語版を買って積読していたのだが、昨年末に本屋で日本語版を見つけて泣きながらレジに…。
主張は、「インターネットでWebサービスを公開するんだったら、メソッドを公開するよりも、 URIにマッピングしてリソースをいろいろ公開したほうがいいよ。そうすると、リソースにブックマークできるし、URLを他人に知らせることが出来るし、リソース同士で相互にリンクも張ることでプログラムがリンクをたどれるし。あとHTTPにはちょうどいい感じでCRUD(Create, Read, Update, Delte)に相当するメソッド(Post, Get, Put, Delete)があるから、公開するリソースへのアクセスはこれらのHTTPのメソッドを使ってさ。で、このコンセプトをROA(Resource Oriented Architecture)と呼ぼうぜ!」といったところか。
これを読むと沸々と「リソースに全部URIをつけて公開するのはいいと思う。意味のあるURLは分かりやすいし。そう思うとWebサービスでない普通のWebアプリもこの規約に従えば、いいことはあっても悪いことはないのではないだろうか?さしてポリシーも無くURLを決めるぐらいだったら、WebアプリでもURLに関してはRESTfulにしちゃってもいいのでは?後でそのままWebサービスとして公開するのも簡単だし。」
などと思ったりしていたのだが、Railsはすでにそうなっていた。以下、Rails2 PDFより
Rails 2 makes no apologies for its all-in attitude about RESTful development and replaces the standard script/generate scaffold with the scaffold_resource functionality from 1.2. The general attitude seems to be “Why wouldn’t you want to create RESTful scaffolding?”.
There’s not much not to like with the RESTful generation – giving you RESTful forms in the view templates and the appropriate RESTful structure in your controllers.
教訓:英語版の技術書を買うんだったら和訳が出るまでに読みきらないと悲しい結果になる
最近、Rubyという言語とRuby on Railsというフレームワークにはまって趣味で勉強してたりするのだが、いかんせん周りにほとんど詳しい人がいないのでつまらん!というわけで週末にRails勉強会なるものに参加してきました。
勉強会の流れは前半と後半2つのセッションにわかれており、事前あるいは当日にみんなで議論してセッション内容を決め、希望者に合わせて前半、後半の時間割と部屋割りをその場で決めてそれぞれ自分の好きなセッションに参加できる形式。運営は非常に完成度が高く初参加の私でも気持ちよく参加できました。
前半のセッションは、Yuumi3さんの初心者セッションに参加。パソコンの無い私は教科書を忘れた小学生のようにテスト駆動開発で有名なt-wadaさんのパソコンで見せてもらう。どうもです。>t-wadaさん。先生を入れて4人という少人数なのでいろいろ聞けました。以下、独学ではなかなか学べない収穫。
後半のセッションは、ほぼ全員が目当てにしている笹田さんの1.9の基調講演セッション。やはり1.9.1はクリスマスに出るとのこと。その他、細かい言語使用をどうするかについての熱い議論。一番、おおっと思ったのはブロックパラメーターがブロックローカルになるとかそのあたりの話。
それにしても一人で知り合いもいない趣味の集まりに行ったのははじめてかも。