Singletonはすごい取り扱い要注意なデザパタとつくづく実感した。
YakiBikiのHTMLプラグインでHTMLエスケープが抜けてそうだったので一通り見直し掛けてる内に、みょうな現象が発生した。
- "sys"ロールユーザーでログイン中に、
- 1.
を実行し、 - 2.
を実行するようなHTMLドキュメントを表示してみる。
具体的にはこんなHTMLテキストを表示させてみる。
<yb_ls 適当なページ名 /> ... <yb_recent 適当な件数 />
すると、sysロールなので
結論から言うと、日時順インデックスを操作するDatetimeクラスのインスタンスがgrain_Factory::index()内でSingletonになっていて、
また、何で"sys"ロールでログインしている場合のみ発生するかというと、"sys"ロール「でない」場合はちゃんと毎度ACLを評価した結果をフィルタに設定しているから。つまり"sys"ロールでログインしている場合のみ、DatetimeのSingletonインスタンスに対するfilter設定が、直前に呼ばれたまま残ってしまっているから。
・・・Singleton(とその亜種)って、本当に、頭痛の種だな。
もともとYakiBikiはファイル読み込みが頻発するため、一度インデックスファイルを読み込んだらずっとメモリ上に残しておくことを目的にして、インデックス系のインスタンスはSingletonっぽくしてあるのだが。
なんか、それが無用なトラブルの元になっているように思えてならない。
あと自分、実はDatetimeクラスにちゃんとreset()メソッドを用意していて、これ呼ぶとfilter設定をリセットしてくれる。・・・が、肝心のgrain_Factory::index()で呼んでいなかったΣ(゚Д゚;。
というわけで、対処としてはreset()を grain_Factory::index()でdatetimeが指定された時、Singletonキャッシュから参照を取得後に呼ぶようにした。
なんというか、パフォーマンスを気にしてSingletonにするとろくな事にならないような気がする。*1