ぐらめぬ・ぜぷつぇんのはてダ(2007 to 2011)

2007年~2011年ごろまで はてなダイアリー に書いてた記事を引っ越してきました。

速度的にはまだあまり問題は出てない。

なんかFirefoxIEで体感速度が違う(FFがもっさりでIEが普通に速い)ので、ちょっと気になってxdebugでprofileしてみた。
大体300ms位。検索で。遅い、とは言えないが・・・。
で、よくよく考えたら開発用なので、config.phpSmartyが毎回コンパイルするようにforce_compileを有効化してた。
これを切ってみたところ、大体100ms位まで縮まった。一番処理的に重い検索モードでやってみたところでも100ms前後。問題ない。多重アクセスなどはやってないけど、そもそもがあまり激しいアクセスは想定していないので、ちょっとまだそこは未知数。検索・View系であれば殆どDAOもcache経由になるので、ファイルロックは内部的には発生しないと思うし。うー、アクセスカウンタとかつけたらそうも言ってられないかも。あー、拡張子があれだから、Webalizerと相性悪そうだなー。
preg_matchとsubstrが、HTMLの独自タグ解析上大量に呼ばれているけど、時間的にはあまり食ってない。100msのオーダーでも(文字列処理系総合で)達していない。それよりは、Smartyコンパイル系で、回数はあまり呼ばれていないがなんだかんだで100msのオーダーで食っていたので、そこが無くなった影響はでかいかも知れない。
つまり多分Viewレイヤーでの速度はあんまり気にしなくて良いと思う。多分今後、実際に使ってみてデータ量が増えていった時に、むしろメモリ消費量やDAO/IDXレイヤー(IDXはそんな気にしなくて良いと思うけど)でネックになってくるかも知れない・・・って、そもそもマスタデータ系は3桁オーダーmaxを想定しているからなぁ。4桁レベルは想定してない。そこで問題が出てくれば、yakibiki.netの出番となるだろう。
あとSmarty関連で思い出したのだけれど、$use_sub_dirsと$cache_dirは今回は未使用。動的コンテンツなので、内容が逐次変化する為$cache_dirは使えない*1。また、$use_sub_dirsはWindows環境では上手く動作しない、と公式マニュアルに記述されているし、そもそもSmartyテンプレートの数自体、4桁オーダーには達していない・・・筈。なので、これらは未使用で問題ない、というか使えない。

*1:あー・・・yakibikiモジュールのRawとViewモードについてのみ、限定的に有効かも・・・。でもinvalidするトリガーがなぁ・・・Observerパターン化?

エラー処理ポリシー

個人的には「エラー処理」と一口に片づけること自体が本来はあまり好きじゃない。「エラー」という言葉の意味に惑わされ、本業のとあるPrjで概念が顧客と一致せずかなり長い間言葉のやりとりで齟齬を生じていたからだ。対象の範囲が広がりすぎていて好きじゃない。多分状態や対応する挙動など、「異常」に対する複数の概念を包含してるからかもしれない・・・。

YakiBiki・・・というかいろいろなシステムでもそうだと思うけど、入力・内部処理・出力の組み合わせでプログラムは動いてる。YakiBikiの場合で言えば入力はHTTPリクエスト、出力はHTML。でもこれは階層化されていて、例えばDAOレイヤーであれば入力はデータ配列、内部処理はPHPのファイル入出力と文字列処理、出力はデータ配列か真偽値になる。
で。ぐだぐだ考えたあげく、ようやく以下の感じに落としどころを持って行くことにする。
大体三種類の「エラー」が有りうる。

  • 入力値のフォーマットミス。数値指定のIDが文字列になっている、Validationエラー、など。
  • ロジックとしての例外処理。例えば存在しないモジュール名が入力された、指定されたIDのデータが見つからない、など。
  • PHP関数がこけた時(型が違う時とか)。ファイルI/Oでの失敗時。データファイルのフォーマットが違う時。

これはそれぞれ、対応すべきアクションがある。

  • 入力値のフォーマットミス→ユーザーに報せる。あるいはシステムの振る舞いに依存する。(デフォルトアクションをするなど)
  • ロジックとしての例外処理→システムの振る舞いに依存する。
  • PHP関数が・・・→これが二つに分かれると思う。
    • 発生する事がロジックとして想定されている時:システムの振る舞いに依存する。(ファイルI/OやソケットI/Oでのリトライ処理、あるいはfopenしようとして失敗することがロジックとして想定されている時)
    • 発生する事が想定されていない時:引数の型が違う時。I/Oなどの関数で、失敗することがシステム上ありえない時。
      • 例1 : 全て正常に動いているYakiBikiのDAOで、突然データのカラム数がおかしくなったとき。
      • 例2 : include/require_once()したファイルが見つからない。

で、アクションに着目するとおおよそ結局、次の二種類に分かれる。

  • 開発者を呼ぶ必要が無いエラー:入力値系、ロジック系。ユーザーにとって意味のある出力を返すもの。最終的に、ユーザー側で何らかのアクションを取り、再度システムに入力をできるようにする余地のあるもの。
    • 例:想定外入力値:ユーザー側で入力値を確認し、再度入力できる。
    • 例:重複値検出:同上。
    • 例:0件系:同上、またはアプリケーションとしての別のアクションをユーザーが選択できる。
    • 例:I/O系リトライエラー:これは微妙。ユーザー側のアクションとして、時間をおいてやりなおしたり、ユーザーの動ける範囲で何らかの対処が可能な物。
  • 開発者を呼ぶ必要が有るエラー:前掲の「発生することが想定されていない時」に相当する。ユーザーレベルじゃどうにもならないエラー。例えばファイルパーミッションエラーもコレに相当する。OSのコンソールにログインしてファイル操作をしないとならない。つまり、システムだけではどうにもならずその中まで入らないとできない。

前者については全てプログラミングのロジックとして実装できるし、そもそも全部ロジックでハンドリングしているものだろう。だってシステムの入出力の取り扱いそのものなのだし*1。つまりこれらのエラーは、出力レイヤーで見た場合には通常の出力ルートと変わらない挙動になる。出力も内部処理のレイヤーで制御しているものと捉えられるからだ。
一方の後者、については、出力レイヤーで見た場合にも異常事態である。内部処理のレイヤーからの通常制御が期待できない。システムやアプリによっては全て内部処理のレイヤーで統括している場合もあるのだろうけど、そもそも内部処理レイヤーの実行自体がこける可能性も後者には含まれている。よって、最悪出力レイヤー自体もこける可能性がある。このときの出力は、ユーザー側だけではどうにもならない事が明確に示された出力である必要がある。はっちゃけ、「だれそれに連絡して下さい。」という表示が期待される。

・・・ぐだぐだ考えてきたけれど、結局、そういう事になると思う。YakiBikiでは基本、IDX/DAO系のファイル入出力でのPHP関数がこける・ファイルフォーマットが違う時とかが、後者に分類され、その他は基本全部前者になる。

・・・そんな感じ、かな。

*1:アプリによっては、重複値や0件系が開発者を呼ぶ必要があるエラーに分類されることもあるだろう。分け方はアプリに依ると思う。