見込み発車でカモランドをWiki化したのは良いが,「Wikiのページ内容を変更したときに,その変更の影響を受けるページのApacheのキャッシュをどうやって更新するか」ということが課題として残っていた.

(前回は,VirtualHost全体のキャッシュを一気に消すということを書いたが,日常的にそれをやるのはやっぱり無駄が多い)

有効期限内に(Expiresを無視して)Apacheのキャッシュを強制的に最新化するには,

  1. ブラウザからno cacheのリクエストを送る (CTRL+F5とか)
  2. そのリクエストで起動されるCGIが返すLast-Modifiedヘッダの日時が,Apacheがキャッシュして保持している内容のLast-Modifiedヘッダの日時より新しい

という2つの条件を満たす必要があるのだが, WikiのCGIプログラムでは現状Last-ModifiedにWikiページの更新日時をセットしているので,2.の条件を満たすためにはページ自体も更新しなければならない.

つまり,そのページ自体は本来変更する必要がないのに,他のページの影響を反映してキャッシュを最新化するためだけに,更新日時を繰り上げるためだけの更新を行う必要があるという間抜けな状態.

...これはいかんということで,寝ても覚めてもmod_cacheという感じで悩んでいたが,ようやく解法を思いついた.

  • Last-Modifiedヘッダには,常にその時のシステム日時を設定する

こうすれば上記の2.の条件は常に満たされるので,ブラウザからno cacheのリクエストさえ送ればそのページのキャッシュを最新化できる.素晴らしい.

ただしこのようにLast-Modifiedをどんどん繰り上げてゆくと,本来効くべきキャッシュが効かなくならないか?という懸念があるが,それは問題ないと思われる.以下,考察...

Apache(mod_cache)の動きを見た感じでは, キャッシュの有効期限が切れたページ(or CGI)にブラウザからアクセスがあった場合,Apacheはキャッシュを使わずに実際にそのページ(or CGI)を呼び出す. そして,そのレスポンスのLast-ModifiedとApacheキャッシュのLast-Modifiedを比較し,

  • a) もしレスポンスのLast-Modifiedが新しければ,キャッシュの内容をその内容に最新化してブラウザに返す
  • b) もしレスポンスのLast-Modifiedが新しくなければ,キャッシュの内容をそのまま維持して引き続きそれをブラウザに返す

という動作をしている.

それで,今回のLast-Modifiedがどんどん繰り上がる仕様だと,ここで常にa)が発生することになる.

このように常に b)ではなくa)が発生することで,何か問題があるか?

という話に最終的に集約されるのだが,考えてみるとb)でもCGIを実行してしまうことに変わりはないので,負荷的には五十歩百歩,どちらでも一緒.

最終回へ...


© 2024 KMIソフトウェア