Google App EngineでもDjango使っている人が多そうな気がしますが、僕はDjangoはよく分かりません。Djangoの本は買ったりしましたが1ページも読んでません。Pythonでは普段は大体Flaskを使っています。これぐらいの規模のフレームワークが僕にはしっくり来ます。それで、GAEでFlaskを使って開発しようとしたときのメモです。
[続きを読む…]
Google App EngineでもDjango使っている人が多そうな気がしますが、僕はDjangoはよく分かりません。Djangoの本は買ったりしましたが1ページも読んでません。Pythonでは普段は大体Flaskを使っています。これぐらいの規模のフレームワークが僕にはしっくり来ます。それで、GAEでFlaskを使って開発しようとしたときのメモです。
[続きを読む…]
アナウンスメールです。ハング(hang)するとか、クラッシュ(crash)するとか、互換性バグ(breaks binary compatibility)とか怖い文句が並んでいます。
Apacheほど保守的なリリース方針でもこんなことが起きます。ソフトウェア開発がいかに難しいかわかります。
「Emacsのトラノマキ」の原稿を公開します。画面上のメニュー「ドキュメント」からたどれます。今回の記事は井上が執筆した「EmacsとD-Bus」です。Software Design 2010年4月号の掲載記事です。
今発売中のSoftware Design 2011年6月号の「Emascのトラノマキ」は、Scala界のLady Gagaを目指したいのでIwaGagaと呼んでくれと言ってまわりを困惑させている岩永さんが執筆した「EmacsでScalaプログラミング」です。破壊的イノベーションを感じる記事になっています。
Software Design (ソフトウェア デザイン) 2011年 06月号 [雑誌]
スティーブ・ジョブズをネタにするとアップル信者から何か言われると脅されたので消します。タイトルだけ見て読みにきた人、ごめんなさい。
WebSocket勉強会が5月28日にあります。最初は3月の終わり頃だったのですが、地震の影響でこの日付になりました。3月の時はアリエルのおおたにさんも何かしゃべる予定だったのですが、今回は調整が付かずにあきらめたそうです。
私は手術のせいだと思っていたのですが、本人はその日は子供の運動会の日だから、と言っています。
今回はwebsocketについての勉強会みたいですが、html5にはクライアント間のP2P通信の仕組みが策定中だったりします。html5はwebsocketに限らずまだまだ目が離せません。
2011/5/10 以下の訂正をしました。
s/prefetch/preflight/g
JavaScriptのクロスドメイン通信で微妙な話があったので書いてみます。ちなみにクライアントサイドJavaScriptの話です。下記仕様に敬意を表して以下ではクロスオリジンと書きます。一般にクロスドメイン通信と呼ばれているものと同じ意味で使います。
WebブラウザからXMLHttpRequest(XHR)で外部のWeb APIを直接叩こうとするとクロスオリジンの制限に当たります。制限の必要性は次の説明がわかりやすいのでリンクを張っておきます。
クロスオリジン制限がある中でWebブラウザから直接Web APIを叩こうと先人は知恵を絞ってきました。iframeを使うハック的手法はマッシュマトリックスに任せておくとして、一応メインストリームな手法のひとつがJSONPです。JSONPを知らない人は自分で解説記事を見つけてください。
JSONPを使うにはWeb API提供側がJSONP対応する必要がありますが、JSON対応済みであればJSONP対応は容易です。JSONPは一応動くので現状のクロスオリジン制限を回避する手法のデファクト標準です(たぶん)。JSONPを初めて聞いた時はその巧妙さに関心しましたがこれがメインストリームの技術でいいのか、という疑念があります。そもそもJSONPにはハック臭がします。ハックはハックでメインでいいのかという思いです。たとえると、園川一美が開幕投手でいいのかに通じる思いです。scriptタグを動的生成する辺りに気持ち悪さがあります。jQueryなりのライブラリを使えばこの辺りの実装詳細が隠れるので気にしなければいいのかもしれませんが、JSONPはなにか違います(主観です)。
JSONPに代わるクロスオリジン制限回避手法のHTML5時代?のデファクトかと思うのがpostMessageです。postMessageを使うと別ドメインのWeb APIを叩くiframeを作って、元ドメインのHTMLとiframeの間で文字列の受け渡しができます。iframeをWeb APIを叩くバッファのように使ってクロスオリジン制限を回避できます。postMessage自体は綺麗なAPIだと思いますが、Web APIを叩く手法としてはやはり微妙なハック感が否めません。これもjQueryなり適当なライブラリが詳細を隠蔽すれば気にならないのかもしれませんが違和感は残ります。ロッテつながりでたとえてみると、渡辺俊介が開幕投手をするぐらいの違和感です。渡辺は良い投手だと思いますが開幕投手の格なのか、と言われると疑問です。
長い前振りが終わってようやく本題のXHR2です。
クライアント側のAPI的に美しいと思うのがXHRでそのまま別オリジンのWeb APIを叩ける手法です。冒頭に挙げたふたつのリンク、Cross-Origin Resource Sharing(CORS)とXMLHttpRequest2(XHR2)です。CORSはHTTPの世界の話で、XHR2はクライアントサイドJavaScriptのAPIの世界の話です。XHR2とありますが、クロスオリジン制限回避のためには普通に従来どおりのXHRのコードを書くだけです。XHR2に対応したWebブラウザはCORSに従ったHTTPリクエストを投げてくれます。
CORSのHTTPリクエストにはOriginリクエストヘッダがあります。リクエストURLが別オリジンのXHR呼び出しをすると、XHR2対応のWebブラウザが自動でOriginヘッダをつけてくれます。XHR2未対応の場合は別オリジンのXHR呼び出しはリクエスト自体を投げないので既に動作が異なります。Originヘッダのあるリクエストを投げてレスポンスを受けても、レスポンスが条件に合致しないとXHR2対応のWebブラウザはそのレスポンスを捨ててしまいます。条件の詳細は省略しますが、とりあえず一番簡易な場合にはAccess-Control-Allow-Originレスポンスヘッダの条件にパスする必要があります。
XHR2の簡単な動作検証のためには、リクエストを受ける側のApacheに次の設定をします。このApacheはクロスオリジンでWeb APIを叩くシナリオでWeb API提供側に当たるサーバです。
1 2 3 |
# apacheのCORSの設定例 LoadModule headers_module modules/mod_headers.so Header append Access-Control-Allow-Origin * |
クライアントサイドのJavaScriptのコードを3パターン載せます。XHR直呼び版、prototype.js版、jQuery版です。
今回の話の本質ではありませんが次のHTMLとレスポンスJSONを前提にしたコードです。
1 2 |
<div id="click" onclick="doit()">click</div> <div id="data"></div> |
1 |
{"data":"foobar"} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// XHR direct <script type="text/javascript" src="prototype17.js"></script> function doit() { var req = new XMLHttpRequest(); req.open('GET', 'http://別オリジンのホスト/ret.json', true); req.onreadystatechange = function(evt) { if (req.readyState == 4) { if (req.status == 200) { $('data').innerHTML = JSON.parse(req.responseText).data; } } }; req.send(null); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// prototype.js <script type="text/javascript" src="prototype17.js"></script> function doit() { new Ajax.Request("http://別オリジンのホスト/ret.json", { method: 'GET', onComplete: function(res) { var result = res.responseText.evalJSON(); $('data').innerHTML = result.data; } } ); } |
1 2 3 4 5 6 7 8 |
// jQuery <script type="text/javascript" charset="utf-8" src="jquery16.js"></script> function doit() { $.get('http://別オリジンのホスト/ret.json', null, function(res) { $('#data').html(res.data); }, 'json'); } |
さて、今日の本題の本題ですが、これだけではprototype.js版が期待どおりに動きません。答えはSのつくサイトにもありますが、CORSに非標準のリクエストヘッダがある場合にpreflightと呼ばれるフローがあるのが原因です。preflightはOPTIONSメソッドのリクエストを事前に投げてサーバとネゴシエーションをします。
prototype.jsのAJAX呼び出しは内部で次のような独自拡張のリクエストヘッダをつけます。これがCORSのprefetchを誘発します(prefetchはXHR2対応のWebブラウザがXHR呼び出しの内部で自動で行います)。
1 2 3 4 5 6 7 |
// prototype.js 1.7から抜粋 setRequestHeaders: function() { var headers = { 'X-Requested-With': 'XMLHttpRequest', 'X-Prototype-Version': Prototype.Version, 'Accept': 'text/javascript, text/html, application/xml, text/xml, */*' }; |
Apache側に次の追加設定をするとprototype.js版も動作するようになります。
1 2 |
# apacheのCORSの追加設定例(prototype.js) Header append Access-Control-Allow-Headers x-prototype-version,x-requested-with |
めでたしめでたし、と言いたいところですが、この結果に納得はしていません。Access-Control-Allow-Headersレスポンスヘッダは誰がつけることを想定しているのか疑問です。今回のようにApacheの設定でハードコードするのは、動作検証ではいいですが実用的には変に感じます。では、WebアプリがOPTIONSメソッドに対するレスポンスを返すべきなのでしょうか。もしそうだとしてもAccess-Control-Allow-Headersヘッダの値に何を返していいのか分かりません。
そもそも独自拡張のHTTPヘッダがあるだけで動作が変わるのは罠にしか思えません。独自拡張ヘッダは行儀が良いとは言えませんが深い考慮なしにつける人も多そうです。頭にX-をつけておけば、知らない人は無視してくれるだろうことを期待している気がします。
やはりpostMessageが本命APIでしょうか。
ubuntu 11.04がリリースされて、unityがデフォルトになっています。unityはOpenGLで3Dが有効になっていないと使えません。最近のPCであれば気にする必要はないですが、VMWareなどの仮想マシン上で使う場合は、3Dが使えません。つまり、unityが使えません。あれ?VirtualBoxもParallelsも3Dは使えるので、ひょっとしてVMWareだけ?些細なことは気にしません。さて、それで、unity-2dをインストールして使います。でも、unityでもカスタマイズは結構やっかいでCompizの設定をcompizconfig-settings-managerをインストールして、難解な設定を行わないといけません。それでも、できる設定は限られています。unity-2dはCompizの設定からは設定できません。unity-2dを設定するには、gconf-editorを起動して設定します。
[続きはこちら…]
pypy1.5がリリースされました。JITコンパイラを搭載するなどしていてCPythonより速いという触れ込みです。何もしなくても自分のプログラムが高速になっていくというのはとっても楽です。でも、pypyって日本語で響きは卑猥なのでちょっと避けてました。嘘です。では、本当に速くなるのか、というのをフィボナッチ数列を計算する例のプログラムで試してみます。今回は再帰するコードと再帰しないで計算するコードの二つで計測しています。それから、参考までにJavaの計測時間ものせています。ただし、本来のJavaのコードがそうであるように、Fibonacciを計算するファクトリクラスを作って、何とかパターンでごにょごにょごにょ、っていうのはやっていません。誰かエンタープライズ用途で計算する壮大なプログラムを書いてください。さて、それでは今回計測したコードたちです。
[続きはこちら…]
ビッグデータを征す クラウドの技術 Hadoop&NoSQL
発売は既に2週前ですがムック「ビッグデータを征す クラウドの技術 Hadoop&NoSQL」が出ました。以下の過去のASCII.technologies誌の記事がそのまま載っています。
新規の書き下ろし記事も書きました。タイトルは「NoSQLとはなにか?」です。
パーティショニング(シャーディング)とレプリケーションのふたつの側面に注目してNoSQLを解説しました。合わせてCAP定理も説明しました。CAP定理の解説記事は、特にWeb上で初期の頃に書かれた記事は、微妙にごまかされた気分になるものがあります。たとえばCAPのPは分散を意味するので外せない、だからCとAのどちらを取るかを決めなければいけない、などと説明されても納得できません。少なくとも自分はこういう説明に納得できません。
どこで読んだか忘れたので記憶違いかもしれませんが、Pをクライアントとサーバの間のネットワーク分断耐性だと説明しているページがありました。これは明らかな誤りです。クライアントから見て、ネットワーク障害でサーバにつなげないことと、サーバそのものが落ちてつなげないこと(CAPのA)は、CAP定理の視点では違いがありません。Pをこのように解釈したらAと同じことを言っているだけになります。
Pはサーバとサーバの間のネットワーク分断の耐性です。この耐性を考慮する必要があるのはサーバ間でレプリケーションをした場合です。では、なぜレプリケーションが必要かと言うとサーバが落ちた時の可用性(A)のためです。Aを上げるためにレプリケーションを非同期にすると古いデータを読む可能性があり一貫性に支障がでます(CAPのC)。とこんな感じにこれ以上続けると記事の再録みたいになるのでこの辺でやめておきます。記事はもう少し丁寧に書いています。
NoSQLの話は「実践JS サーバサイド JavaScript 入門」にも書きましたが、このムックと補完関係になっています。NoSQLのデータモデルに関しては「実践JS サーバサイド JavaScript 入門」のほうが詳しいので書籍を読んでください。分散処理の話はムックにしか書いていません。
参考までにCAP定理の証明論文のリンクを張っておきます。
この論文の良い点は短いところです。全12ページですが、事実上の証明部分は2ページもありません。悪いところは、(自分だけかもしれませんが)ごまかされたような気分になるところです。
この論文のもうひとつ良い点は、CAP定理のよくある質問「CAPのCとACIDのC(あるいはA)って同じですか?」に対して明解に回答が書いてあるところです。いちいち論文を読む人はいないと思うので答えを書いておくと「違う」が回答です。どう違うかは論文を読むか(3ページ目の脚注3)、ムックの記事を読んでください。
会社のUbuntuも11.04にアップグレードされていしまいましたしました。仮想マシン上の家のUbuntuとは 違い、直接インストールしています。インストールは2時間ぐらいで終わったと思いますが、もっと時間がかかっているかもしれません。unityは賛否両論 があるみたいですが、僕は頑張って使い続けます。と言うか、あんまりこだわりがないだけですが・・・。さて、今まではUbuntuのIMEは何も考えずに Anthyを使っていました。でも、ちょっとオバカさんなのでGoogleのMozcをインストールしました。
[続きはこちら…]
最近のコメント