2010年8月29日日曜日

Kindle3 使ってみた

Kindle2と比較してみて

- 縦横とも1cmほど小さくなった。
これによって、片手でつかみやすくなった。
DSCN1681

- コントラストの改善
今回購入した理由の一番にこれを期待して、購入した。
家の証明は暖色系が多く、Kindleで本を読むと暗く感じるときがある。あとひっくり返ってよむとどうしても暗くなってしまうので、画面がより「白い」方が良い。ただ確かによくはなっているものの改善はわずかだった。左の画像がKindle2、右の画像がKindle3。右の画像の方がわずかに白くなっているのが分かると思う。もっと「白く」なって欲しいと思う。
DSCN1679DSCN1680

- 軽くなった
実際に計ってみたところ、Kindle2は293g、Kindle3は226グラムと67g(23%)ほど軽くなっている。実際に持ってみたところ、小さくなった関係もあり、Kindle2より大分軽く感じる。持って読むときも大分腕の負担が軽くなる。
DSCN1683 DSCN1684

- ページ送りが速くなった。
大分速くなったように感じる。iPadのiBookでPDFを見た場合、ページ送りの時表示されるまでそこそこ時間がかかるが、それよりも速いかもしれない。

- 容量が増えた。
Kindle2の1.48Gから3.09Gに増えている。自炊したファイルはサイズが大きいので大きい方が良い。

- ある程度日本語に対応した。
日本語ファイル名が表示可能になった。自炊していると非常にありがたい。ただ、PDFの日本語はフォントが埋め込みでなければ相変わらず表示できないようだ(未確認)。あとブラウザも日本語入力は出来ないが日本語の表示が出来るようになった。googleを使った場合、ちゃんとサジェストも動作するのでローマ字入力だけでもそこそこ使える。また3Gモデルであれば、ブラウザの機能は現状はExperimental(実験)とされているので、通信料も取られない。(多分。Kindle3になって変わっていたりするかもしれない。念のため。)
Evernoteが読めれば結構最高なんだが、Webからではちょっと重くて使い物にならなかった。今後に期待!

- PDFファイルのコントラストの変更が可能
自炊したファイルをKindleで閲覧していて良く困るのが、字が薄すぎて読めない!ということがよくあること。スキャナにScanSnapを使用している場合、読み取り方式を「白黒」にして、読み取り濃度を濃く、にすれば特に問題ない。しかしその場合、「白黒」のため途中に画像などが挿入されていると画像が潰れてしまう。かといって読み取り方式を「自動」にすると、今度は「画像」があるページがカラーで読み込まれKindleで見た場合、画像は見やすくなるが、字が薄くて読みづらくなる。
この場合、Kindle3ではコントラストの設定の、lightest lighter default darker darkestと選択できるなかのdarkestを選ぶと薄い文字が濃く表示され、ある程度読みやすくなる。

- まとめ
全体的に良くなったと思う。とはいえ、未だに日本語の本の電子書籍は販売されないし、その予定もない。早くそのあたり解決されるともっと良い。また、日本語対応やコントラストの変更など、ソフトウェアで対応できるものは、Kindle2でアップデートできるようにして欲しい。

2010年6月15日火曜日

iPad使ってみた

今回購入は見送ろうと思っていたが、気になってしかたないので、購入してしまった。買ったのはWiFi 16Gモデル。正直このエントリーを書くのは、iPad発売から大分時間がたってるし、もうじきiOS4が出るわでタイミングが悪い、、

結論

ここ一週間ほど使ってみた感じ、まだまだ改善点は色々見られるものの、今後のOSアップデートによるサポートもあるし、また飽きて使用済みになれば、親にでもあげて使ってもらえばいいと思う。高級なフォトフレームにもなるし、レシピブックにもなるだろう。
トイレやお風呂場にでも貼り付けておいても良いかもしれない。WLAN経由で動画も見れるし、音楽も聞ける。
自分の場合昔からタブレットPCにはあこがれのようなものがあり、以前使っていたノートPCは8.9inch液晶のコンパーチブル型のタブレットPCだった。これはこれで面白いPCだったが、ネックになったのは重さ(1.23kg)とバッテリー(二時間弱)だった。そのタブレットPCを買った当時は12万ほどした。それから3年ほどでiPadが登場し重さは680gになり駆動時間が10時間になり、価格は5万円になった。
PC(Windows)以上のことが出来るかというと、それは人によるから何とも言えないし、仮にPCを使ったことがないユーザにiPadを無条件に進めれるかというとそういうわけでもない(iTunes必須だし)。ただマウスとキーボードというインターフェースから切り離されるだけで、ベッドでごろごろしながら使ったり、車の中で使ったり、使い方は人それぞれだが可能性は広がる。興味があるのであれば買ってしまっても良いと思う。逆にあまり興味がわかないのであれば無理して買う必要も無い。多くの場合iPadは自分で使い道を探さないといけないから。

iPod touchとの比較

  • 純正メールアプリ
    画面が大きくなり使いやすくなった。横画面状態であれば、メールのリストと内容が同時に表示できる。これとGmailがあれば、PC版のメールソフトなんか要らなくなるんじゃないかと思う。Gmailについてはアーカイブにする操作ができないので惜しいが、、
  • 純正写真アプリ
    画面が大きくなったことで、より細かくきれいに見れるようになった。特に人に見せるとき、iPod touchでは画面が小さく、出来ればPCの高解像度画面で見て欲しいときがあると思う。そのような場合に、さっと相手に渡して操作させることの出来るiPadはとても良いと思う。
  • 純正ビデオアプリ
    今回購入したのは16Gモデルなので、音楽を入れてとか、動画を入れてとかは余り考えていなかった。いつも家で動画を見るときは、主にDLNAを使ってPS3で見ている。やはり洋画などはこの方式で見た方が、映像もきれいだし、音も5.1chのAVアンプで再生されるので良い。純正ビデオアプリではDLNAは再生できないが、他のアプリを使って、主にアニメ等、映像も音もそこそこ見れれば良い場合など、ソファーにごろんと座ってDLNA経由でiPadで再生するようにすると、ファイルの一元管理も出来るし、意外と快適だった。
  • 純正iPodアプリ
    iPod touchがあるので、さすがに使っていない。少し試して見たところ、よりiTunesに近いようなインターフェースになっているように感じる。アルバムアートワークがとても大きく表示されるので、iPod touch用に用意した解像度の低い画像では粗く表示されるじゃないかと思う(ここは試してない)。
  • Webブラウザ(Safari)
    ブラウザは基本的に画面が大きくなっただけだろうか。個人的には別画面への移動や、画面を閉じるのが意外と面倒で、リンクを行ったり来たりするのに時間がかかるのを何とかして欲しい。あとiGoogle使ってると別画面に移動して戻ったときに再読み込みがかかるような挙動になるのを何とかして欲しいところ。Safari5からは拡張機能が使えるようになるという話なので期待。
  • 電子書籍
    画面が大きくなった分とても見やすい。ただ雑誌のようなA4サイズを拡大縮小なしで読もうとすると少し厳しい場合がある。拡大縮小しながら読むのはめんどくさい。
    また液晶の品質は良くも悪くもiPod touchと同じように感じる。自分の場合この液晶を長時間見ていると目が若干ちかちかして集中して読めなかったり、目が疲れたりする。この原因(推測)としては、画素が粗くドットが見える、液晶が手前のガラス面より少し奥まったところにあり、手前のガラスの写り込みと液晶面がずれる、iPadのような端末は画面を近くで見る為右目と左目で感じる輝度に違いがある。これらの原因で焦点を合わせずらくなり、結果目が疲れるんじゃないかと考えている。
    ホリエモンやその他の人達が、携帯やパソコンなど、みんなずっと液晶見てるんだから、目が疲れるなんて事はないと言ってたりするが、確かに自分も一日中PCの液晶を見ているがそう疲れを感じることはない。なのでiPadやiPod touchはこれらとはまた違うように思う。ただ次期iPhone4の液晶は凄く良さそうだ。期待。
    写真 
  • Bluetoothキーボードが使える
    今この文章の下書きはiPadに接続したBluetoothキーボードで書いているが、意外と快適。使っているキーボードは以前Windows Mobileに接続して使っていた変則配置のキー四段しかない折りたたみ式のキーボード(iGo Ultra-Slim Keyboard)。ソフトウェア(ディスプレイ)キーボードについては、慣れればそこそこ入力できるかもしれないが、今のところはそこまではためしていない。少し使ってみた感じ、画面の上に手を乗せると手が邪魔になってしまいキーが見えなくなり、また通常のキーボードとは配置が違うので、ブラインドタッチが出来ないので、結構ストレスが溜まる。慣れてブラインドタッチが出来るようになればそこそこ快適になるかも知れない。また、ソフトウェア(ディスプレイ)キーボードが意外と不便に感じるのは横画面だと画面の半分近くがキーボードで埋まってしまうこと。
    Bluetoothキーボードについては、iOS4でiPod touchでも使えるようになるかもしれない。
    DSCN1606
  • ファイルの連携が出来る。
    iPod touchではzipファイルが添付されてきた場合などどうしようもなかったが(多分)、これがiPadでは特定の関連したプログラムにファイルを渡せるようになった。これにより、zipファイルを添付されてきた場合でもGood Readerなどのアプリにファイルを渡し展開し、閲覧することが可能になった。また、Good Readerからほかのアプリにファイルをコピーして開くというようなことも可能になった。

Kindleとの比較

  • 重さ・大きさ
    まず最初に持って見た感じ「重い!」。Kindleが289グラムに対して、iPadは680グラムもありずっしりしている。これはある程度最初から予想はしていた。よくノートPCと比較して軽いと言われるが、やはりKindleや普通の本と比較すると重く感じる。またiPadは形状的に片手では持ちにくい形をしている。片手で持とうとすると淵の部分をつかむ感じになり、この持ち方だと回転方向にテコの原理が働き意外と握力がいる。Kindleはもともと軽いのもあるが、下にキーボード部分があり、その上のスペースの辺りを掴むと自然な感じで掴める。また横幅が13.5cmなので手の幅に収まりガシッと片手で掴める。
    また今回はApple純正のケースを使用しているが、これが意外と重く合計すると874グラムもある。正直重くて参ったが、他の背面につけるタイプのケースも100グラム程度あるのと、純正ケースの場合ふちの部分に引っ掛かりが出来、若干持ちやすくなるので、まぁ良いかなということにした。
    DSCN1623
    DSCN1607 
  • 見やすさ
    総合的に見れば、iPadの方が上だろう。ただKindleの方が手軽な場合があり、これは例えば、白黒でKindleの画面に1ページが収まるような、文庫本サイズや文字の大きい本など、また自分の場合、Kindleの方が目との相性がよいのでKindleで読めるものはKindleで読むスタイルにした。

Flybook(8.9inch液晶 コンパーチブル型タブレットPC Windows7)との比較

DSCN1299

  • ブラウザ(Safari)はいまいち
    やはりPCのChromeやFirefoxのブラウザと比較すると物足りない。拡張機能が使えないためAutoPagerのような拡張機能や、タブの使いやすさなど不満が残る。Windows7(Vista)のタッチパネルの場合、8方向のフリック(指をはじく操作)に機能を割り当てることが出来、これにそれぞれ、戻る、進む、ページスクロール、ページを閉じる、拡大、縮小などを割り当てて操作していたが、これはこれで快適だった。
  • IMEが頭悪い。
    時々閉口する。我慢すれば何とか使えるレベル。
  • 電子書籍
    WindowsでPDFを見ようとすると、主にAdobe Readerを使うと思うが、タブレットで操作した場合これの操作性が悪いこと、、正直スペックが下(多分)のiPadでこれだけなめらかに操作できるのに。iPad(Apple)を見習って欲しいところ。
    ただ、PCの場合Windows SearchでPDFの横断検索が出来るため、まだまだ捨てられない。なのでiPadは電子書籍を読むことには向いているが、電子書籍から何かを探そうとするのには全然向いていない。
  • バッテリーが持つ
    バッテリーが凄くもつのはとても良い。一日の使用であれば気にすることは無いと思う。ただ、寝るときに充電し忘れると、通常のUSBポートではスリープ状態にしないと充電できないし、スリープにしたとしても、満充電までは凄く時間がかかる。これは通常のUSBポートでは5Aまでしか電流が流せないためで、よくUSB HDD等に付いている、USBを2つのポートを占有して電源を確保するケーブルがあるが、あれのiPad版は発売されないだろうか。
  • 使いやすさ
    WindowsはWindows7になって大分改善されたが、元々タブレット用には作られていないため、やはり使いにくい。また、ハードウェアの使いやすさとして、車の中で使ったりする場合、iPadであればダッシュボードの上にぽんと置いておいたり、運転席でハンドルが邪魔でも操作できたりするが、ノートPCの場合ダッシュボードに置いておくのは何かと気を遣うし、運転席側でキーボードを打って操作するというのは厳しい。

2010年5月20日木曜日

Doctrine 関係リンク集

次のプロジェクトはDoctrineでいくことにしたのでメモ。
Doctrine2ではマジックメソッド(findBy~)が使えなくなるらしいし、そもそも処理が重いらしいので開発では使わないことにした。

初級編

上級編

2010年3月25日木曜日

symfony 1.4 + Propel 1.4 でメモリリーク?

さて、以前とあるWebサービスをsymfony 1.0からsymfony 1.4へアップデートを行ったが、バックエンドのバッチ処理は1.0のまま稼働させていた。また、とある事情でこのWebサービスを整理する必要があったため、バッチ処理の1.4化を行っていた。

いくつか、1.4化のための作業(ログ関係とヘルパー関係の修正等)を行いバッチ処理を開始!様子を見ていると1.0時代より非常に時間がかかる。さらに待っていると、良くあるメモリが足りないよ!というFatal Errorで死亡してしまった。あれ-、、と思いつつメモリの様子を見て見ると・・・

memory_leak

美しすぎるメモリリークの図

メモリリークしてる!あーこんな情報前に何処かで見たなと思いつつ検索してみるも発見できず、、

仕方ないのでソースコードを少しずつ実行して原因となる場所の特定をする。複数箇所で起きているようで、どうもPropelのオブジェクトを生成するときにリークするようだった。

この時点でもしかしたらリークしているわけではなく、なんらかのキャッシュ機構が働いているのかもなぁ、と思い検索して見るも発見できず。グーグルで「Propel 1.4」で検索するとこのブログが上から三番目に出てくるという、情報のなさっぷりを嘆く。

ここまでくるとソースを見るしかない。オブジェクトの生成部をたどっていくと、Propelが自動生成したBaseDataSourcePeer.phpで以下のようなソースを見つけた。

	public static function populateObjects(PDOStatement $stmt)
	{
		$results = array();
	
		// set the class once to avoid overhead in the loop
		$cls = DataSourcePeer::getOMClass(false);
		// populate the object(s)
		while ($row = $stmt->fetch(PDO::FETCH_NUM)) {
 			$key = DataSourcePeer::getPrimaryKeyHashFromRow($row, 0);
 			if (null !== ($obj = DataSourcePeer::getInstanceFromPool($key))) {
 				// We no longer rehydrate the object, since this can cause data loss.
 				// See http://propel.phpdb.org/trac/ticket/509
 				// $obj->hydrate($row, 0, true); // rehydrate
 				$results[] = $obj;
 			} else {
				$obj = new $cls();
				$obj->hydrate($row);
				$results[] = $obj;
        DataSourcePeer::addInstanceToPool($obj, $key);
 			} // if key exists
		}
		$stmt->closeCursor();
		return $results;
	}

注目して欲しいのはDataSourcePeer::addInstanceToPoolというメソッドで、名前からして、キャッシュしてますよ!という香りが漂ってくる。試しにPropel1.2で生成したモデルと比較してみると、1.2移行のバージョンで新しく追加されたことがわかった。また上記メソッドを使用している部分を全てコメントアウトしてみると、メモリが異常に消費されることは無くなった。

さてここまでわかれば、検索でさらにキーワードを絞ることが出来る。再度検索してみると、原因はdatabases.ymlでpooling:trueと設定していることであった!(参考)databases.ymlに書いてあるあたり基本中の基本だ!何となく、へーpoolingするんだ?速そうだからtrueにしとけ、的な感覚でtrueにしたのを思い出した、、

まとめ

マニュアルはちゃんと読もう。

少し追記。場合によっては、オブジェクトをプールした方が高速になる場合があるのはわかる。しかし自動でORMで処理してしまうのは費用対効果(メモリ消費とCPU・ディスク負荷の軽減)を考えるとあまり良い方法ではないように思う。今Propel1.4で実装されているような処理では、私が遭遇したような問題が起こるかも知れないし、キャッシュヒット率を考えると、ヒット率が良いと考えられる場合はアプリーケーションレベルで都度実装した方が多くの場合よりよいだろう。

また単純に何も考えずにアプリケーションを実装した場合、今回のようなオブジェクトプールにメモリを回すよりはDBにメモリを回した方がより効果は得られるだろう。なぜなら、各種DBはメモリをより効率的に使うため極限まで最適化され、常に開発が続けられているからである。またPHPのプロセスと違い常に起動しているものなのでよく使われるデータのみをキャッシュするなど最適化もしやすい。例外的にCPU負荷がとても高く、メモリが余っておりオブジェクト生成がボトルネックになっているような場合はオブジェクトプールをtrueにしても良いと思う。

2010年3月19日金曜日

Google App Engine + Windows

  • dev_appserver.py すると HTTPSHandlerがないよって言われる。
    ActivePythonのx64版をインストールしているならx86版をインストールする。
  • 公式のチュートリアルを一通りやる。
  • 本番にアップしようとappcfg.py updateをするとSSLモジュールがないよって言われる。
  • http://pypi.python.org/pypi/ssl をインストールしてねって言われるので、ダウンロードして
    python setup.py install
    するとこのPythonはVisual Studio 2003でビルドされてるよ!Visual Studioでコンパイルするかcygwinでためしてね!っていわれる。
  • しかたないのでcygwin版でやってみる。すでにpython2.5がインストールされていた。
  • ActivePythonはとりあえずアンインストールする。
  • cygwin版pythonで
    python setup.py install
    すると成功した。
  • appcfg.py updateも成功して無事本番にアップ完了した
    http://hanger35.appspot.com/

まとめ

Google App Engineを使うときはcygwin版pythonを使おう。

2010年3月4日木曜日

symfony1.0 から symfony1.4 への移行メモ

メモ書きなので品質低
まずsymfony1.0を1.1にアップグレードプロジェクトを1.2から1.3/1.4にアップグレードする1.3の廃止予定および削除される機能に目を通す。バージョンが違うが参考になると思う。翻訳して頂いた方々に感謝。
OpenPNE プラグイン開発者のみなさんにsymfony1.4 対応のお願いもちょっと参考になる。

pluginが読み込まれない

symfony1.4では一つ一つ手動でconfig/ProjectConfiguration.class.phpに設定する必要がある。
Symfony tutorial参照

また、フォルダの名前を何とかPluginにする必要がある。1.0はplugins/testのような名前でも大丈夫だったが、ソースを見た感じplugins/testPluginのように、Pluginという文字がフォルダに付いてないと認識しない。

Propel

PropelはPrope1.2.1-devlからPropel1.4にバージョンが上がっている。

1.4ではDB抽象化レイヤに使っていたCreoleをやめて、PDOを使うようになっているので、PDOのExtensionをインストールする。config/databases.ymlはdsnという項目が追加されている。generate:projectしたときに作成されているサンプルを参考にdsn形式で書く。

クエリを直で実行したいときに使う、Propel::getConnection()で帰ってくるインスタンスが、以前のCreoleのインスタンスからPropelPDOと変更になっているのでこれに依存してるコードはエラーになる。自分のコードの場合、ExecuteQueryみたいな関数を用意していたので、とりあえずNextやgetRow関数等を実装したアダプタを間に挟んで返すようにして対応した。また、build-modelで自動生成したモデルの何とかPeerクラスのdoSelectRSはなくなり、代わりにdoSelectStmtが追加されている。他ORM経由でクエリを処理する場合はいまのところ特に問題ないと思う。

稼働中のDBからモデルを再生成する。propelのDB設定ファイルconfig/propel.iniは1.0のものをそのままコピーしてもbuild-model時にエラーになるので、公式ページを参照して再設定する。 
symfony propel:build-schema --xml
symfony propel:build-model
以前のバージョンのPropelでもbuild-schema時に生成されるschema.xmlをそのままbuild-modelしようとするとエラーに成る場合があるが、今回のバージョンでもやはり直ってないようだ。DBはMySQL。その場合、schema.xmlのDATEやTIMESTAMPのdefault=””を削除したり、CURRENT_TIMESTAMPとあるところを'0000-00-00 00:00:00'とすると直るかも知れない。

TEXTで定義したフィールドは自分の環境だとCHARSETをbinaryにしているためか、propel:build-schemaで自動生成した場合BLOBになってしまっている。その場合Propel1.2.1-devの時は問題なかったが、単純に->getFieldName()とした場合リソースが返されるだけで、値が取得できなくなっている。その場合fgets( $resouce )等すれば取得できが、今回はbuild-schema --xml時に生成されるXMLを編集して、type=”BLOB”と成っているところを、type=”LONGVARCHAR”と変更して対応した。

web debugツールバーで実行したクエリを表示するにはログを取る必要がある。ログを取る場合は、databases.ymlでDebugPDOを指定する。

Propel1.4の新機能については下記のブログが参考になる。
Propel 1.4のWhatsNewの超訳

フォーム・バリデータ関係

1.0でのvalidater.ymlやhandleErrorメソッドなどのVlidate処理は、sfForm関に吸収されたような形になっている。

このあたりは気合いを入れて書き直すしかないと思う。フォームが多いシステムの場合移行に際して一番大変になると思う。sfFormはなれれば割と使いやすいと思うが癖が強い。ただフォーム処理なんて言うのは大体こういうものなので気にしないこととする。自分の場合表示には使わずバリデータにしかつかっていない。フォームをプログラムで自動生成するのはデザインとの関係もあるので余り好きではない。

ビュー関係

component slotを使用していて、ビューをmodule.ymlで変更しているとき、別のモジュールから他のモジュールのcomponent slotを呼ぶとビューの変更が適用されず、デフォルトのsfViewPartialで実行されエラーになる。この辺の設定はモジュールごとに設定されているためだが、カレントのモジュールの設定しか読み込まれないためエラーになる。仕方ないのであまり良い方法とは思えないが、defaultモジュールを別途設定するために適当な場所に下記のコードを入れて対応した
sfConfig::set('mod_default_view_class','hrPHPTAL');
sfConfig::set('mod_default_partial_view_class','hrPHPTAL');

また、デフォルトのビュー(sfPHPView)を使用している場合、デフォルトで自動的にエスケープされるよう修正されているので修正する必要がある。

 

ルーティング関係

クラス構成やメソッドが大きく変わっているため、依存しているコードがあれば作り直しが必要になる。大体代わりの機能は用意されているので頑張って書き換える。

YAML関係

YAMLのパーサがSPYCからsfYAMLとなり、YAML1.2の仕様となった。大きな変更点として、offやnoは文字列として扱われるようになり、修正が必要になる。一部symfony側でoffやnoの場合でも、偽となるよう処理されているところもあるが、cache.ymlでoffと指定しているのにキャッシュされてしまうなどの問題もあったので、offやnoは全部falseに書き換え、onやyesはtrueに書き換えた。
またSPYCで通っていたものがsfYamlでエラーになる。
自分のパターンでは、正規表現を指定する部分で、例えば、 type: [a-z]{1,3}と指定しているとエラーで、これをtype: “[a-z]{1,3}”と指定してやれば問題なくなった。{}はYAMLでは連想配列を指定するのに使うので微妙な扱いの変更だと思う。

キャッシュ関係

CacheHelperについては以前書いたのでこちらを参照。

アクションキャッシュについては、sfViewCacheManager->setSuffix()(違うかも)が無くなってしまったため、ログインが必要なページでログイン前とログイン後で別々のキャッシュファイルを生成するようにしていが、それが出来なくなってしまった。そのため別途FileCacheクラスを作成して対応した。

まとめ

今回symofny1.4へ移行した理由は、symfony1.0のサポートが切れ、今後も長く続くプロジェクトでシステムの拡張・修正が必要だったため。Propel関係はうまくやれば修正にそれほど時間はかからないが、フォームの修正、キャッシュ関係の修正、動作確認にかなりの時間が必要だった。特に理由がない限り既存のプロジェクトをsymfony1.4に移行するのはあまりオススメできない。
そういえば上記には書いていなかったが、admin generatorも移行に相当時間が必要そうだったため、symfony1.0のまま運用してお茶を濁している、、これも追々移行したい。

2010年2月18日木曜日

symfony 1.4 CacheHelper(cache関数) のその後

前回のまとめ

symfony 1.4のCacheHelperには余分なキャッシュを保存してしまう問題がある(多分)。sfViewCacheManagerのソースを見た感じでは、module名とaction名のみを基準にキャッシュ管理をしており、独自の内部URI(default/indexのような)をもたないcacheは制御が行えず、action cacheも同時に保存してしまうような仕様になっている。

対策

結局別にCacheHelperを作成する事で対応した。元々symfony 1.0の時からCacheHelperでは対応できない機能があったので、別途CacheHelperを作成して対応していた。

ソース github ライセンスはMIT

追加した機能は

  1. 前回のブログで書いた余分なキャッシュを保存しないようにした。
  2. 別途引数にinternalURIを追加して、複数のページで同一のキャッシュを使用できるようにした。
  3. すでにキャッシュ済みか調べるための関数の追加した。

使い方

  • cache関数の代わりにhr_cache関数を使用する。
  • cache_save関数の代わりにhr_cache_save関数を使用する。
  • hr_is_cached()関数はactionですでにキャッシュ中か調べて余分な処理を行わないようにするようなときに使用する。hr_is_cachedを実行した際の結果はstatic変数に保存され、その後hr_cacheが使用されたときと結果が同じになるよう保証する。(実行されるタイミングが異なるため、lifetimeが切れて結果が異なる場合があるため)
  • 第三引数のinternaURIは例えば、URIが値を取る場合、’default/index?a=123’と’default/index?a=abc’では別のキャッシュが保存されるが、internalURIに’default/index’と指定することで共通のキャッシュが使用される。

効果

  • ディスク領域の節約になる。
  • internalURIを適切に設定するとキャッシュヒット率が上がり各種負荷が下がる。

本来であれば、componentを使えば良いが、componentを使うとtemplateファイルが分離され、設定も多少煩雑になるため、自分の場合どちらかというとCacheHelperを好んで使っている場合が多い。

ただ、殆どの場合通常のCacheHelperで問題はないと思う。効果があるのはページ数が数万~数十万単位あるサイトで、キャッシュ書き込みによりディスク負荷があがり、キャッシュファイルの増大によって(Linux等のOSの)ページキャッシュが圧迫されパフォーマンスが急激に低下するような場合それなりの効果があると思う。