Ktouth Brand. on Web

け〜くんこと K.Ktouth のだらだらした日常と突発的に作るプログラムや読み物とかの雑多サイト



[2011年03月18日]

Rack のクッキーの有効期限と Sequel/Ramaze のセッション情報キャッシュ

2011年05月31日 17:42更新 筆者:K.Ktouth

Rubyベストプラクティス -プロフェッショナルによるコードとテクニック(AA)

先日、Ramaze + Sequel でセッション情報が復帰出来ないという内容の話題を書きましたが、その続き。
どうも Sequel、Ramaze 双方ともリファクタリングの際にコードの最適化を行った結果、特定条件下におけるエラーを内包しちゃった……という感じのようです。細かいことは下記参照。
加えて Ramaze がサーバーとの対話に使っている Rack にも特定条件下におけるエラーを発見しました(ぉ

どちらも英語圏のプロダクトだし、Rack はともかく Sequel、Ramaze の方は全く別のプロダクトにまたがるトラブルなんでどこにどう連絡すればいいのやら。機械翻訳ではうまく伝えられない気がひしひしとします(笑)
とりあえず ruby-list ML の方に投げてみましたが、昨今のネットワーク自粛ムードのなか、レスポンスがいつ帰ってくるかも微妙…… ^^;

両方に共通するのは「おそらく ruby 1.9.2 なら正しく動作する?」という点。全くテストしていないわけがないので。
…… CGI 起動のコスト低減のためも含めて、ruby 1.9.2 ベースに書き直す?げー

(以下、今回のエラーのまとめ)
(11/05/31追記:各ライブラリの状況の変化を追記しました)

Rack、クッキーの送信時に有効期限の指定が無視される

Rack 1.2.2 にて確認。

response.set_cookie('foobar', :value => 'bazbaz', :expires => Time.now + 10 * 86400)

Rack 環境にてクッキーを設定する際には上記のようにします。が、ruby 1.8.7 mswin32/mingw32 版では時間指定が空になります
原因は Rack::Utils.rfc2822 モジュール関数の最後、strftime の引数に %T を使っているせいのようです。
%T 自体は strftime のリファレンスマニュアルのフォーマットには書かれておらず、環境依存するもののようです。windows 向けの strftime(3) では存在せず、空文字が返ってくる……そういう挙動です。
ruby 1.9.x のリファレンスマニュアルの記述を見る限りはC言語に丸投げではなく自前で処理しているらしく、問題は顕在化していないようです。

公式の github を見ると、2月11日にまさしくその対策が行われているのですが、3月にリリースされた 1.2.2 には反映されていません。パッチのレビュー中なのかも。適当なパッチを自前で当てておいて、とりあえず様子見かなぁ?
(追記)11/05/23 公開のrack 1.3.0にてパッチが適用されているのが確認出来ました。最新版へのアップデートをお勧めします。

Sequel + Ramaze、特定条件下にてモデルのカラム参照に失敗する。

こちらは前回の内容を参照

Sequel 側はserialization プラグインのリファクタリングが行われた際にコードが最適化され、super() が使われるようになったせいのようです。
公式の github を見ると、メソッド定義部分を define_serialized_attribute_accessor として分離しているんですが、その際に @values[column] から super() に書き換えてられています。この部分が @values[column] の場合は問題ありません。

Ramaze 側はこのバグを認識していたらしく、古いバージョンのコードにはハックコードが書かれています。が、これがこのリファクタリングの際に綺麗に消されていますげー
同時にこのデシリアライザを呼び出す Ramaze::Cache::Sequel#cache_fetch メソッドもリファクタリングされ、例外を握りつぶす仕様に更新されたせいで発見しづらい状況になっているようです。

とはいえ、この二つのリファクタリング、各々の内容を見る限り、特に間違ったことをしているようには見えないんですよね……
となると。クラス構造を大きく変化させる要因となる Sequel::Model の schema プラグインの設計を見直せというサインじゃなかろーかとか思ったり思わなかったり。
そもそも Sequel::Model ってテーブルの構造変化をモデルクラス反映させる方法がアンドキュメントだったりするし(ぉ、その辺きちんと煮詰めないとパッチも書きにくいのかも……
# テーブルのスキーマを変更後、Sequel::Model.set_dataset メソッドに改めてテーブルを突っ込めばいいとは思うけど、それだけだとアソシエーションとかがきちんと反映されていないっぽい……?

(追記)11/05/31現在、githubのリポジトリの方ではテーブルの定義・保存機構を serialization および schema プラグインに頼らず自前で準備するという手段で対応しているようです。
gem の公開はまだ行われていませんが、いずれ対応バージョンが上がると思われます。

本日のリンク元
その他のリンク元
検索