CGI::Session
CGI::Session

とある開発中のASPのテスト中の出来事。
CGI::Sessionで作ったセッションの値をクリアしているのに、別の画面にいくと復活している。
おかげで、後続の処理がおかしくなっていた。
最初は某K君曰くリダイレクトがうまくいってないのかも、という話だったのでそこら辺を疑ってみたがどうも解決しない。

とりあえず、そのASPはmod_perl環境で、しかもApache::Registryだったことを思い出した。
で、キャッシュされているんだろうとあたりをつけて、いろいろやってみた。
apacheのハンドラでリダイレクトしていたので、そこら辺をキャッシュさせないようにしても駄目。
うーん、とCGI::Sessionのドキュメントにらめっこしてたところ、

flush()

バッファ内のデータをディスク内のそのコピーに同期させます。通常はプログラムが終了する直前にあなたが呼び出し、sessionオブジェクトはスコープから外れるか、あるいはclose()が呼び出されることになるでしょう。

キタ━━━ヽ(ヽ(゚ヽ(゚∀ヽ(゚∀゚ヽ(゚∀゚)ノ゚∀゚)ノ∀゚)ノ゚)ノ)ノ━━━!

無事にキャッシュもフラッシュされて、直りました。mod_perl しかも Apache::Registry おそるべし。

おまけ。


mod_perl【Apache::Registry】と【Apache::PerlRun】の違いって?

■ Apache::Registry
実行コードをメモリ上にキャッシュすることによって200~2000%の高速化。
変数のスコープ、初期化などを厳密に行う必要がある。

■Apache::PerlRun
Perlインタープリターをメモリに常駐させることによって高速化を計る。
スクリプト自体のコンパイルは毎回行われるので動作はまあそこそこ速い程度。
(とはいえPerlRunでも十分速いですが。)

参考:
http://www.omakase.org/mod_perl.htm

※ 2008/07/03 追記
CGI::Sessionとは

mod_perl環境下で使う場合の注意

CGI::Sessionクラスはデストラクタでセッション情報のシリアライズを行っています。このため、mod_perl環境下で使用するとGC で回収されるまでいつまでたってもシリアライズされず、セッションが維持できないということになります。mod_perl環境下では明示的にflushメソッドを呼び、シリアライズするようにします。

$session->flush();

ということだそうです。