baserCMSで、プラグインや拡張機能を作る際に、留意した方が良いキャッシュの動作がわかったのでシェアします。
発生する条件
- モデルで BcCache を利用している場合
- 例: BlogPost, Page モデル等
- getConditionAllowPublish() のように、find 時の conditions の条件に、日時判定を利用している場合
キャッシュが動作する際の仕組み
モデルのデータキャッシュは、以下のような仕組みで動作する。
- キャッシュファイルは、以下のパスに保存される
- /app/tmp/cache/datas/mysite_pg_blog_posts
- ※モデル別に保存ディレクトリのパスは異なる
- キャッシュファイルのファイル名の命名規則は、conditions の条件をシリアライズ化し、キャッシュのファイル名としている
- 保存する際に、conditions の条件をシリアライズ化している
- シリアライズ化したものを、ファイル名に設定している
- conditions の条件で取得した結果を、ファイルとして保存している
動作による影響
- getConditionAllowPublish() のように、日時を判定している箇所については、1秒毎にキャッシュファイルが生成されてしまう
- ※ キャッシュファイルの無限増殖に繋がってしまう
- conditions の条件により、大量のデータを取得するケースがある場合、取得したデータはキャッシュファイルに保存される
- キャッシュファイルの容量が大きくなり、サーバのHDD容量を圧迫することに繋がるケースがある
- キャッシュファイルの1ファイルのサイズが15MB等になるケースもある
わるい動作例
OptionalLink の場合
- バージョンが 2.4.5-beta 以降
- 対象ファイル: OptionalLink/Event/OptionalLinkHelperEventListener.php
$conditions = $BlogPostModel->getConditionAllowPublish();
$this->blogPostList = $BlogPostModel->find('all', array(
'conditions' => $conditions,
'fields' => array(
'id', 'blog_content_id', 'no', 'name', 'blog_category_id', 'user_id', 'status', 'posts_date',
),
'order' => 'BlogPost.id DESC',
'recursive' => 2,
));
修正後の内容
find を利用する際のオプションに「cache => false」を設定する。
こうすることで、キャッシュファイルを生成しない動作とすることができる。
$conditions = $BlogPostModel->getConditionAllowPublish();
$this->blogPostList = $BlogPostModel->find('all', array(
'conditions' => $conditions,
'fields' => array(
'id', 'blog_content_id', 'no', 'name', 'blog_category_id', 'user_id', 'status', 'posts_date',
),
'order' => 'BlogPost.id DESC',
'recursive' => 2,
'cache' => false,
));
まとめ
キャッシュを利用しているモデルで、データの日時や期間を見るような検索条件を利用する場合、
'cache' => false,
の指定を忘れず入れるようにしましょう。