2011年12月10日土曜日

開発進捗(12/10)

Pytho2.5のままだと将来的にきつそうなので、Python 2.7で頑張ることにしました。
(OrderdDictも欲しかったし)

Python2.5のときは、フルスクラッチで フレームワークを作ってました。今回はまた1から作り直しますが、前回とは違って、なるべくwebapp2を利用することにします。
あんまり開発に時間をとれないんだから、些細なことには拘らずに、手早く作ることをめざします。

今のところwebapp2で気にくわないのは、routerのところと、そこから先のハンドラの部分なので、そこをいじればいけるかなと。

htmlのレンダは、昔は日本語のドキュメントがあるフレームワークがみあたらなくてきつかったので、自作してました。でも今はjinja2の日本語のドキュメントあるので、jinja2で良いかな。Sphinxでもjinja2が標準ですしね。
本当は、前の自作のと比べるとimport が重くなりそうなので、jinja2を使うのはちょっと嫌です。でも、動的な遅延インポート+ハンドラのキャッシュで、レンダリングには ほとんどパフォーマンスは要求されないはずなので、手を抜くことにしました。

環境の再構築はだいたい完了。
当面の目標は検索画面の作成ですね。

タスク1:検索先のマスタの作成
  1. Mechanizeで とりこみたいデータを取り込むようにする
    →例外的なところを除けば取り込めるようになった。例外部分は後回しにしよう
  2. 取り込んだデータをもとに、辞書を定義するpythonスクリプトを出力するモジュールを作る
    →これから着手
タスク2: 検索用のフォームの作成

そういや、webapp2 についての記事が微妙に人気みたいですね。
googleの検索でひっかかりやすいので、一番ページビューがあります。
webapp2については、googleの公式には日本語のドキュメントがないので、困っている人もおおいのかな?
でも英語わからなくても、Python語がわかるなら、webapp2は頑張れば使えますよ!

2011年12月8日木曜日

GAEの課金額の変更について

課金額の変更ですが、あんまりいっぱいGAEを使っていなかったので、だいぶ乗り遅れてました。

今更情報収集したのですが、
を整理すると、こんな感じですかね。
  • CPU利用時間ではなくインスタンス時間で課金。
    Front Endのインスタンスは、のべ28時間分OK。
    つまり1インスタンスだけなら、24時間無料枠でOK!
    BackEndは別に9時間分の無料枠がある。
  • 課金モードにすると、最低でも月9$かかる
  • データストアへのアクセスは高価。
    特に書込でインデックスがいっぱいあるとキツイ。
    エンティティのサイズはあんまり関係ないらしい。
  • 全体的に無料枠が激減。
    一人や家族くらいまでなら大丈夫だけど、一般に公開するとなると普通は課金が必要

無料で広告費を稼ごうかなぁとかおもっていた人(←私のことです)的には、残念な話ですね。

でもまあ、元々が安すぎたと思うので、仕方がないかなぁと思います。
特に、データストアへのアクセスは、インフラに負荷をかけていたと思うのでしかたないかなぁと。



考えられる対策としては、

データストアのチューニング:
  • Memcache をばりばり使う
  • なるべく大きいエンティティを使う (普通のDBみたいに正規化とかしない。親子は一つにまとめる)
  • インデックスは押さえる。なるべくキーを良く考えて設計し、そこに情報を詰め込む。
  • マスタ類は、コードにべた書きの辞書にする

インスタンス時間のチューニング:
  • Python 2.7 で スレッドセーフにして、1つのインスタンスで捌けるトランザクションを増やす
  • BackEndを有効活用する
  • 「Max Idle Instance」は「1(最小)」にする
  • 「Min Pending Latency」は「15s(最大)」にする

他にも良い方法を見つけたら思いついたら上に追記していきます。

Mercurialって日本語大丈夫になったのですね!

Sphinxで書いたドキュメントをバージョン管理していなかった理由は、使いたいと思ったツール(Mercurial)が、日本語のファイル・フォルダ名をうまく扱えなかったことが一番の理由でした。

(バザールは、日本語使えるようですが、シェルエクステンションがいまいちっていう評判を聞くので、おっさん的にきついので・・・)

 ですが、現在の最新バージョンは、日本語でも大丈夫みたいですね。
試しに入れてみた(tortoisehg-2.2.1-hg-2.0.1-x86.msi)のですが、以前はうまく認識できなかったファイルやフォルダも、ちゃんと認識されてますね。

よーし。これなら本格的に使えるぞ!
日本語のパスはダメとか、Windows上で仕事を進めてるとありえなかったんですよ。

本格的にチュートリアル(JapaneseTutorial)とかやってみることにします!


Mercurialを知らない人はこちら→Wikipedia


追記:

あれ? これって、win32mbcsのエクステンションがデフォルトで動くようになっているだけなんじゃ・・・

2011年12月7日水曜日

IE9 と localhost

GAE SDK 1.6.0 がリリースされ、Python2.7がちゃんと使えるようになったらしいので、環境を再構築してみました。

以下、ポイント
  • Python2.5をアンインストールして、Python2.7のみの環境にしてからGAE SDKを入れたら、警告らしきものが出た。 (でも動くらいしい)
  • 私はWindows7の64bit版を使っているので、Python 2.7 も64bit版をインストール。しかし、PILモジュールは、64bit版に対応していないらしい?(インストールしようとするとエラーになる・・・)
  • Eclipseは、Pleades3.7(32bit)の一番軽いやつに、pydevを追加。
  • Windows7(64bit) + Python 2.7(64bit) + Pleades3.7(32bit) 上で、webapp2のHello worldは普通に動いた
  • でもSDKのバージョンのチェックの際に404エラーになっている・・・なんでか不明。
  • IE9だと、localhostを開くときもsmartscanが動いてしまうらしい。そのせいで、Eclipseでgae sdkをテスト実行しているときに、IE9でなかなか開けないという現象が発生した。
    GAE SDKからIE9を起動すると、IEの設定を一部オフにするらしく、普通に開ける。
    1時間近く無駄にして、大変な憤りを感じてしまったので、Chromeをインストールした。
IE9でも、互換モードにしたりプライベートモードにすれば、localhostを普通に開けるようになるのかも知れないのですが・・・、いちいち調べるのが嫌になったので試してません。

Eclipseだけ64bit対応じゃないので、いつか64bitにしたい気もする。
あとは、MySQLのインストールか・・・。できれば今晩チャレンジしたいな。

Sphinxの同期

Sphinx、良いですね。


前にもちょっと書きましたが、テンプレートを自分用に修正して、
htmlからソースのrstファイルをテキストエディタで開くボタンと
htmlを再生成するバッチを起動するボタンを追加してみました。

おかげで、個人用wikiみたいに使えていて良い感じです。

 同じ職場のチーム内で共有したほうが良い資料は、
共有フォルダで公開してます。

rstの同期は、
分散バージョン管理とかでやるのが良いのでしょうが、
mercurialを 勉強するのが 面倒でやれてません。

なので、昔ながらのbatファイル&タスクスケジューラで同期をとっているのですが、
先日、ネットワークにつながっていない状態で不具合を起こしてしまい、
ローカルのrstファイルが削除されてしまいました。

1.共有フォルダにカレントを移す
2.ファイルを全部削除
3.XCOPY

ネットワークにつながっていなかったので、1が失敗し、
ローカルのファイルを削除してしまったわけです。

まぁ、元々の書き方に問題があったわけだし、
分散バージョン管理しろ、ってことなのでしょうが、
今更仕組みを再構築するのもだるいので、
robocopyを使って同期取ることにしました。
これだとファイルの削除も一緒にやってくれるので、安全です。

XPは、robocopyが無かったので、以下のサイトからリソースキットを落としてインストールしました。

WindowsServer2003の英語版リソースキット(XPの日本語でも動くらいしい)


追記:

本件、一生懸命作っていたファイルが削除されてしまった怒りから書いてみたのですが、
どうみても、自分が悪いだけですね。

2011年11月25日金曜日

Python:半角で文字数を数える

なんとなく必要になったので、いろいろ調べて以下に落ち着きました。



def hankaku_count(text, wide_type_letters='WFA'):
    u"""半角で何文字かを数えます

    あいまいな文字を1文字で数える時は、
    wide_type_letters='WF'でお願いします。
    (デフォルトは2文字です)

    Example:
    
    >>> hankaku_count(u'テストtest')
    10
    """
    import unicodedata
    return (len(text) + 
            sum(1 for char in text 
                if ord(char) >= 256 and 
                   unicodedata.east_asian_width(char)
                   in wide_type_letters
               )
           )

# EOF


2011年10月25日火曜日

携帯サイトのセッション管理

携帯電話のセッション管理の面倒さは、ドコモの携帯がクッキーに対応していないことに起因している。(他のキャリアについては、パソコンとほぼ同じと考えていい)
新しい機種やスマホは、当然クッキーに対応しているのだけれど、古いドコモを切って良いのかどうかで迷い中。

ぶっちゃけ自分の携帯は、クッキーに対応しているので、古いドコモはとりあえず切って開発しようかな?
うん、そうしよう。

速さを重視して、データストアにまったく値を保存しないで、memcacheでセッション管理したら、memcacheの寿命が短すぎてまいった。端末のcookieにはセッションIDが残っているのですが、サーバ側はセッションIDやそれに紐づけられた変数が数分で消える。
memcacheのエントリの寿命は2週間を指定しているのに、すぐおちるのは、インスタンスが落ちるのと同じタイミングでmemcacheも落ちるということかな?
みんなcookieに保存するのもありだけど、改ざんテストにコストがかかるし、古いドコモに対応させようとするとURLクエリに保存しきれなくてきついはず。
ってことはやっぱりセッション管理にデータストアを使うしかないのかなぁ。
普通でつまらないけど、仕方ないかな。

Sphinx良いですね

自分の仕事用の手順書をまとめるのに使用してみました。
構造化した感じのwikiをローカルで構築できるので、重宝しそう。

難があるとすると、
1.日本語の扱いが微妙
2.ビルドするのが面倒
3.ビルドしたhtmlからソースを編集できない

1.はパッチがあるので、それを適用すると何となく動きます。
2と3は、気合でhtmlをいじって、なんとかワンクリックでできるようにしてみた。

・・・結構、快適ですねぇ。
だらだら書いてもそれっぽくなるので、文章の内容に集中できるし、
あとから編集するのも楽。
これは広めていこう。

2011年9月7日水曜日

webapp2! の続き

ビジネスロジックはいじらずに、あいかわらずフレームワークをいじってしまってます。

webapp2のハンドラの文字列によるインポートは、ちょっと誤解してました。
ディスパッチャでは別の使い方をしているので、私のフレームワークとは別物ですね。
webapp2は、全体にモジューラルな感じに作られていて、いじりやすそうですが、書き方が冗長すぎる気もします。webapp2を分解してもう少しインテグラルな方に作り直してみよう。
前回webappを分解して自分用フレームワークを作ってみた時は、GAEの仕組みを大分理解できましたので、今回もいろいろ勉強になりそう。

旧フレームワークの改善点:
・requestやresponseを、ハンドラオブジェクトの属性に保存しない(並列実行時にオブジェクトの属性が書き換えられる場合があることを考慮する)
・ディスパッチャからハンドラのgetやpostのメソッドを直接呼ばないようにする(ハンドラ側でセッションIDの管理を行ってから、getやpostを呼ぶようにする)。そうすることで、ハンドラごとにセッションを管理するかどうかを制御できるようにする。
・view部分をもう少し高速化できるようにする。(文字列の結合を減らせるようにする)

最近は仕事で少しだけpythonを使うようになっているのですが、2.7のほうが良いことがおおいので、GAEにもはやく2.7になって欲しいです。

2011年9月6日火曜日

webapp2!

webapp2が、自分の作っているフレームワークとほぼ同じで笑った。
文字列によるハンドラのインポートとか・・・
ハンドラを一度インポートした後使いまわすところとか・・・
セッション管理とか・・・
ほとんどやられちゃってる!

んー。フレームワークまわりは一度放っておいて、業務ロジックを作っていこう。

2011年5月27日金曜日

開発進捗(05/27)

mechanize遊びばっかりやってました。
よく調べてみたら、リクエストを出せばgreeの掲示板のコメントは削除できたので、
あんまりjsonは関係ありませんでした。
(コメント削除の結果はjson形式で帰ってくるのですが、あんまり意識する必要はない漢字でした)

本筋のMTG-Guildsのほうは、さっぱりですが、
Wikiの仕様を一部取り込むとメニュー処理を標準化できそうなので、
その方向で検討中です。

・・・いいから、セッションを早く実装しよう。

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をそのまま使ってもとりあえずよかったので回り道をしていますが、
中身をいじったおかげで仕組みが少しわかったので、これはこれでよかった。

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

2011年1月5日水曜日

Google App Engine(Python)のフレームワーク

柴田淳さんのブログを見ていたら、
Ahaというフレームワークを(いまさら)見つけた。

http://coreblog.org/ats/looking-back-2010

なんだか、すごく出来がよさそうなので、参考にしてみることにする。

mercurialをインストールして、
hg clone https://aha-gae.googlecode.com/hg/ aha-gae

んー。コメントは日本語じゃないのかぁ。
でも勉強がてら読んでいこう。