2011年3月28日月曜日

開発進捗(03/28)

いちおうハンドラを再入可能にしてみた。
要はインスタンスに変数を保存するとダメなんですね。固定部分のみ保存して、それ以外は、request か BigTable か memchachから取得しないといけない。

なんのかんので がんばっていろいろ最適化したところ、スピンアップは100ms~300ms(cpu_msは50くらい)くらいになった。このハンドラを使って、身内用の災害用掲示板を作ってみたけど、無駄に高速でよい感じ。一般に使えるアイデアを練ってます。

あと、mechanizeの使い方を勉強してみた。これは便利だ。
その副産物でSNS(GREE)にアクセスできるようになった。jsonでの通信を組み合わせられれば、なんでも出来るんだけどなぁ。(掲示板のコメントの削除だけは、パソコンではjson経由でないと受け付けてくれない。他はリンクをクリックするアクションでOK)

今後の課題は、セッションの管理かな。
memchachオンリーで良い気がしているんだけど、保存期間的に無理なのかなぁ。

2011年2月4日金曜日

開発進捗(02/04)

メインとなる処理の振り分けのハンドラが出来た。

前は、アップロード前にローカルのスクリプトを実行して、
以下のような定義をメインハンドラのスクリプトに書き込むようにしてました。

from sites.index import requst_handler as sites_index_html
site_tree = {'index.html':sites_index_html}

ただ、こうすると、サイトツリーが大きくなってくると、
最初のインポートの負荷が高くなってしまう。

だから、リクエストハンドラとビューを分離して、
リクエストハンドラが呼び出されたときにビューをimportするようにしてみた。
でも、リクエストハンドラは最初に全部importすることが必要だし、
分離するとわかりにくくなって微妙。


いろいろ調べた結果、結局、urlを文字列変換して動的に
リクエストハンドラをインポートして、呼び出せばよいことになった。
 例)http://hogehoge/index.htmlへのリクエスト
  urlを解釈して動的にインポート
    a = __import__("sites.index")
  その後で、
    instance = sites.index.request_handler()
    instance(request, response)
  みたいな感じ。

ついでに辞書に、"url":リクエストハンドラのインスタンス
という形で保存していけば、2回目以降は アプリケーションキャッシュが残っていれば高速になる。
だいたいこんな感じかな。
  site_tree = {}
  
  def main():
    if url in site_tree:
      instance = site_tree[url]
    else:
      instance = urlを動的にインポートしてinstanceを作成する処理(url)
      if instance is not Null:
        ファイルが無いよと表示して処理を終了
      else:
        site_tree[url] = instance
    instance(request, response)

最初からサイトツリーを全部構築するのではなくて、
リクエストされたスクリプトを__import__して サイトツリーを育てていくわけですね。


あと、wepbappだと、リクエストがある度に
毎回ハンドラオブジェクトのインスタンスを作成しているのですが、
毎回 作るのは微妙な気がしたので、最初だけつくるようにしてみた。

でもよく考えてみたら、そうした場合、リクエストハンドラが再入可能でないといけない。
今は globalの変数にレンダリング用の文字列を保存し、それを直接更新してレスポンスを作成しているので、現状ではダメ。
なるほどー。だからwebappは毎回インスタンスを作成しているのかぁ。

でもちゃんと設計すれば、毎回作る必要はないはず。
初心者向けのラッピングと判断し、リクエストハンドラを歳入可能にすることにした。

2011年1月22日土曜日

開発進捗(1/22)

目立った進捗は無し。

テンプレートを入れ子にしても速度が保てる方法を考えていたのですが、
いい案が思いつかない。

思いつかないんで、携帯サイトの作り方について以下のサイトで勉強しました。

http://kachibito.net/web-service/mobile-site-tips.html

http://dspt.blog59.fc2.com/

xhtmlを使ったほうが良い、という話は参考になりました。
htmlベースにして考えていたので、危なかったです。


それによく考えたら、携帯の画面ではそんんなに複雑なことを表現できないので、
テンプレートの多重化はそんなに気にしなくて良い気がしてきました。

ただ、キャリアによって表示を多少分けたほうがよいので、
うまくそれを吸収しながら遅くならないようにする方法は考える必要がありそう。

selfに持たせていた属性の一部をclassに持たせたほうが良いかもね。

2011年1月18日火曜日

開発進捗(1/17)

やったこと:
  ページのhtml部分を別ファイルにして必要になったらimportさせるようにした。
  htmlの各要素のオブジェクト生成は、import時にのみ実行させるようにした。

結果:
  全体的にみると、ちょっとだけ速くなっているようだ。
  起動時間はあんまり変化なし。理論上はほかのページをimportしない分速いはずですが・・・
  考えられる原因:
    初回のフォームの生成が2重処理になっていることが原因か?
      import時に空フォームを生成。
      レンダリング時にリクエストの値をフォームに埋め込み
    あとは、ページが少ないので、1ファイルだけimportする恩恵が少ないこともありうる。

  表記がこなれていないし、オーバーヘッドももう少し抑えられるような気がする。
  テストコードは全然できていない。

進むべき方向をしらべている場合は、テスト駆動型開発って難しい気がする。
デザインがきっちり決まっていないと、テストコード書いても無駄が多いような?

次にやること:
  ・表記やオーバーヘッドを減らすコードを考える。
  ・リクエストの値を簡単にフォームに埋められるようにしたい。
  ・オブジェクトの生成をキャッシュ化しているけど、
   固定文字列を生成するところまでキャッシュ化させられるようにする。
  ・テストコードを整備する。
  ・リファクタリング開始。

2011年1月15日土曜日

開発進捗(1/15)

app.yamlの定義を自動生成してハンドラーごとに呼び出す作戦は、パフォーマンス的に思ったほどの効果はない(とういかむしろ遅くなった)ようだった。そのため、そっちの道はあきらめる。

そうなると、webappでだいたいOKなのですが、中身を細かく見ていくと、無駄に思える機能や使い方がよくわからない機能がいくつかありました。
なるべく起動を軽くしたいので、ソースをコピーして、自分用に最適化。
・正規表現でハンドラーを定義する仕組みは、不必要なので廃止。
 ディクショナリにパスを定義して、リクエストされたパスと完全に一致するパスに割り当てられているハンドラを呼び出すようにする。それにともなって、後ろのパスを渡す処理もなし。
・lib_config.registerの意味がよくわからなかったので、取っ払う。
・googleアカウントは使わない予定なので、login_requierdは、完全に作り直す必要がある。とりあえず廃止。
・webappで使用するモジュールを一つのモジュールにまとめる。
・class RequestHandlerは、htmlを生成する自作モジュールへ統合。
・ビューとコントローラのファイルを分割し、各ビューは対応するコントローラが呼び出されたときにインポートするようにさせる。

ここまでやったのですが、全体にサイトが小さいのでいまいち効果がわからない。
webappをそのまま使ってもとりあえずよかったので回り道をしていますが、
中身をいじったおかげで仕組みが少しわかったので、これはこれでよかった。

ビューは、テンプレートを初回のインポート時に作成して、
以降はテンプレートへのあてはめをしていけば良いはずですが、そうなっていない。
そこを直して、速度を確認していこう。