2008年04月30日

HTTP::Engine - Perl版 WSGI のような物、 Catalyst::Engine を抜き出したような物

先週のCatalystConでHTTP::Server::Wrapperというのを発表したのですが、やっぱり名前長いしわかりにくいよねということで、HTTP::Engineという名前でやり直して CPAN に上げました。
http://search.cpan.org/dist/HTTP-Engine/
実は Catalyst の svn repos に HTTP-Engine のディレクトリ掘ってある事は知っていたんだけども、4ヶ月くらい前に作ってからそれっきりっぽいので、DISられ覚悟でうpたわけです。

簡単に説明すると、mod_perlやfastcgiやHTTP::Server::SimpleやPOEやCGIなど様々なWebエンジンを透過的に扱って簡単にフレームワークとか、ちょっとしたオレオレWeb Serverが楽に作れるモジュールです。
PythonでいうとWSGI、RubyでいうとRackのPerlバージョンと考えて下さい。
昔から Catalyst::Engine と Catalyst::Request と Catalyst::Response だけ分離して使いたいよねという話が持ち上がってて、話すだけで実装する所まで行かなかったんですが、CatalystConがあったので Class::Component ベースで作ってみたくなって作りました。

最初のうちは CodeRepos の中でちまちまコンセプト作り上げて YAPC::Asia あたりで外に出して Catalyst::Engine 置き換えようよ!とか Jifty で HTTP::Engine 使おうぜ!とか無茶言おうと思ってたのですが、よく考えたら CodeRepos には Jesse が居たわけで
斜め翻訳すると HTTP::Engine よさげなら Jifty で使ってみたい的な事を言ってた様子。

で、いつの間にか mst の耳にも入っていて、 mst から mail が来たので #catalyst-dev に行ってみたら HTTP::Engine ktkr!状態になってました(かなり意訳)
あちらさんも、まえまえからやろうやろう行ってたけど実行出来なかったよんという感じみたいでした。

なんだか、昨夜から怒濤の展開でようやく今追いついたのでエントリ書いた次第。

とりあえず今は HTTP::Engine というのは、どういった形にすればいいというコンセプトを決めるフェーズなので、安定とかそういうのはほど遠いですが興味有る人は開発参加して下さい。今がチャンス!
irc.perl.org の #http-engine に専用チャンネル作ってますです。
とりあえず今は tokuhirom が Moose 版 の HTTP::Engine を作って盛り上がってる所。

Posted by Yappo at 20:04 | Comments (0) | TrackBack

2008年04月23日

HTTP::Server::Wrapper と CatalystConの発表資料

Cisco Catalystシリーズの勉強会という事で参加したのに、全然違うPerlとか良くわからないやつの勉強会でした。
とりあえずCatalystにログインした所からスタートしたんだけど反応がなくて、enした辺りでようやくhiroseさんが笑ってくれました。
とりあえずshow confしたけど無反応で酷い温度差でしたね。

なんだかサンフランCiscoとかPlugin使わないよJKとかいう言葉が飛び交ったり、発表者全てがCatalystをDISっていましね。
nothingmuchがスペシャルゲストとして来てくれたお陰でプチYAPCというか前々前夜祭くらいのノリになっていました。

しょうがないのでCatalyst::Engineを抜き出して再利用できるようにしたHTTP::Server::Wrapperというのを作ったので、それのプレゼンを行いました。
超簡単に説明するとWSGIのPerlバージョン
ただCatalyst::Engineを抜き出しても拡張性がなさ過ぎでいけてないので、Class::Componentを使ってプラガブルに風味にしてあります。
Session処理とか認証処理なんかは基本的にWAF側じゃなくてエンジン側の仕事じゃないかと思っているので、そのあたりもサクッと作れるようにしたい所です。

資料はhttp://svn.coderepos.org/share/docs/yappo/20080422-catalystcon1/catalystcon.pl
一応Partty.orgで録画してあります。
コードはhttp://svn.coderepos.org/share/lang/perl/HTTP-Server-Wrapper/trunk/から。
もうちょっと形を整えたらCPANします。
ついでにhidekさんが開発してるOkinaというWAFにもHTTP::Server::Wrapper対応しときました。

HTTP::Server::Wrapperを使うと本当に簡単にHTTPサーバを内蔵したアプリが書けます。
もちろんWAFとかをこれベースで作るとEngine処理にからむPluginを使い回せるのでとても良いです。
設定

using_frontend_proxy: 1
plugins:
    - module: Engine::Standalone
      conf:
        host: 0.0.0.0
        port: 14000
を書いて、それを実行するサーバアプリは
use strict;
use warnings;
use lib 'lib';
use HTTP::Server::Wrapper;
use Data::Dumper;
HTTP::Server::Wrapper->new('config.yaml', handle_request => sub {my $e = shift; $e->env('DUMY'); $e->res->body(Dumper($e)) } )->run;
こんな感じでブラウザでアクセスしたら、engineの中身を全部Dumpして表示するようなのが簡単に書けます!

HTTP::Server::Wrapperを使ったサーバを書くのは非常に簡単で、newする時に handle_request メソッドを定義すると、ブラウザからアクセスがあるたびに定義したメソッドが呼ばれます。
引数は今の所Engineのコンテキストです。
$engine->req で Catalyst::Request 相当。
$engine->res で Catalyst::Response 相当。
のオブジェクトにアクセスします。

いまコミットしてあるのはコンセプト的な実装で、とりあえず動かすためにSoozy::(?:Engine::HTTP|Request|Response)からのコピペです。
実際これらの大部分はCatalystからのコピペなので、Catalyst::Engineを切り離した感じ。
というコンセプト実装なので、これからより実用的に使えるように皆で変更していったらいいと思います。
名前もそれっぽいのになるといいよね。

ある程度実用的になったらCatalyst::Engine::Wrapperとか書こうと思う。
どうぞご利用下さい。

Posted by Yappo at 11:44 | Comments (0) | TrackBack

2008年04月22日

CodeReposのコミット時のrule撤廃とか

今までCodeReposにコミットする時はプロジェクトパスを入れろてきなルールが合ったのですが、hanekomuや自分を始めとする皆の不満がつのったし、そもそもそんなの機械的にやればよくね?という話も前からあったのでJesseがCodeReposに来たのを記念してルール撤廃しました。

そもそも何であんな変なのがあったかというと、ircbotやfeedで見た時にプロジェクト名がわかり易い方がいいって理由だけだったはず。
それなので、Commit Pingを受け取ってFeedを吐くサーバを書きました。
サーバのコードはhttp://svn.coderepos.org/share/websites/coderepos.org/feedmaker/
Feedはhttp://coderepos.org/feeds/share.xml

でCodeReposのCommit Pingを便利に扱うためだけにCPANモジュールもこしらえました。
Data::CodeRepos::CommitPingです。
Commit Pingのページの下部に書かれたURLのリストにたいして順番にcommitデータのPOSTをするだけなので。
サーバ側で

my $coderepos = Data::CodeRepos::CommitPing->new(CGI-new);
とかするだけで簡単に取り扱えます。

どうぞご利用ください。

Posted by Yappo at 12:40 | Comments (0) | TrackBack

2008年04月14日

ウェブエンジニアをしていて知らないと恥ずかしい日本人プログラマ300

ウェブ関係で仕事をしていて知らないと恥ずかしい日本人100があまりにあんまりでブクマするのも恥ずかしいので、日本のWeb周りでエンジニア(特にプログラマかな)で知らないと恥ずかしい日本のプログラマ(主にWebに関わる的な意味で)100人のリストを作ろうと思う。

今のところ目標の1割くらいリストアップ出来た。まだまだ足りないのでもっと追加する。

14時: いっぱい追加

OPML化はerogeekがやってくれると思うのでOPML作ったよエントリを発見し次第リンクします。
OPML ktkr! yusukebe++
ゆーすけべー日記: ウェブエンジニア(略)と恥ずかしい日本人プログラマ300のブログを列挙祭り

以下敬称略順不同

  • yoshiori - java-ja
  • ats - Python
  • ひがやすお - Java
  • 羽生章洋 - Java
  • mikio - Tokyo Cabinet
  • moritapo - Senna
  • gunyarakun - Senna
  • mir - Tritonn Xen
  • kokogiko - mobile & Geo
  • KENT - CGI
  • kawa.net - Perl Javascript WiiRemote
  • kan - Wema Moxy
  • knagano - emacs clone
  • kacotie - 関係こわし屋 2008-04-16 14:14:25
  • kamawada - erogeek 2008-04-14 16:56:53
  • kazeburo - ロシアのWeb Server インフラ
  • ひろせまさあき - DSAS
  • stanaka - はてなインフラ
  • mizzy - Punc
  • lopnor - 下から上まで
  • HoryGrail - Yahoo top pgae
  • 刺身☆ブーメラン - livedoor
  • machu - Ruby
  • ただただし - Ruby tDiary
  • hiboma - 30days album
  • naoya - はてなブックマーク
  • itomasa - simpleapi
  • 高林哲 - ttyrec
  • typester - TTYShare
  • 古橋貞之 - Partty!.org
  • cho45 - blosxom
  • lestrrat - Perl
  • hio - Perlバイナリアン
  • overlast - chumby
  • halt - 武士道Hacker
  • coji - ssb
  • keisuken - Scala
  • clouder - Imager
  • kazuho - Q4M
  • tomi-ru - ルー
  • babie - RoR
  • bto - CTO
  • fbis - Perl PHP mobile
  • youpy - http://youpy.tumblr.com/
  • nishio - Jython
  • hsbt - Ruby tDiary
  • psychs - Lime Chat
  • drry - robots.txt
  • antipop - lisp
  • akio0911 - Ruby Cocoa
  • tmaesaka - memcached
  • yoshidaster - ZIP
  • brazil - javascript UI
  • yad-EL - SICP ? 2008-04-14 17:42:45
  • shogo4405 - JSmarty 2008-04-14 17:42:45
  • Oliver - /.j 2008-04-14 17:42:45

以下はてなブックマークに続く(で、上記のリストに加える)

Posted by Yappo at 13:00 | Comments (1) | TrackBack

2008年04月08日

HTML::StickyQuery::DoCoMoGUID - iモードIDを使いたい人に朗報

ふと思い立って、DoCoMoが新しく始めたiモードIDを取得するためのリンクを既存のHTMLにたいして簡単に付与出来るモジュールを書いた。
HTML::StickyQuery::DoCoMoGUIDといいます。
使い方はPOD見てね。

iモードは昔からセッションを維持するにはURLのクエリパラメータやPOSTの値にセッションIDを入れないと駄目だったのですが、先月末からクエリパラメータの中にguid=ONが入っていればRequest HEADにiモードIDを入れてくれるようになったんですね。
HTML::StickyQuery::DoCoMoGUIDは渡されたHTMLの中にAタグがあればクエリパラメータにguid=ONを追加してくれるというフィルタモジュールです。
もちろんAタグだけじゃなくてFORMにたいしてもうまく動きます。
FORMの場合はmethodがget/postでguidを入れる方法が違ってくるのですが、これも考慮してくれます。

名前空間が物語っているように、HTML::StickyQueryのラッパー的な実装なのです。
HTML::StickyQueryだとFORM周りの処理をしてくれないのですが、HTML::StickyQuery::DoCoMoGUID側で処理出来るようにちょっと拡張してたりします。
何故かguidの処理をしないモードが搭載されているのでSledgeの

# XXX we need HTML::StickAny or something ...
な需要を満たせるかもしれません。
つまり、HTML::StickyQueryでやってる特定のセッションIDの埋め込みも出来るようにラッピングしてます。

なんでそうやってるかって言うと、iモードIDはhttpsの時に動かないのでECサイトとか作る時には結局HTML::StickyQueryとかでセッションIDを埋め込む必要が出てくるので、iモードIDを取りつつセッションIDを埋めときたいといった需要が満たせるのですね。
一見いままでと変わらなさそうですけどもiモードIDは契約者に対してユニークな物が割り当てられてるので、どんなURLからサイトに訪問されてもセッションIDが使い回せる利点があるのですね。
セッションID入りのURLをブックマークしてもらう必要とかが無くなる。

正直、今までHTML::StickyQueryとか使ってなかったので、現在は別のべすとぷらくてすがあるかもですが、もし無いようでしたらどうぞご利用下さい。

Posted by Yappo at 23:31 | Comments (0) | TrackBack

2008年04月07日

Class::Component 0.14 でてました

HTTP::MobileAttributeと共に成長期に入っているClass::Componentですが、先週末にバージョンアップしちゃってて今回は二つの機能追加を行ってました。

一つめはregister_methodで、登録するmethodとしてpluginで実際に定義されていないメソッド名を利用出来るようになりました。

package Foo::Plugin::Hoge;
use base 'Foo::Plugin';
sub bar : AliasMethod('baz') {}
みたいな感じで書いておくと
$self->call('baz');
した時にbarメソッドが呼ばれます。
あと、もいっこ大きな事としてコードリファレンス渡しも出来るようになったので無名関数もプラグインメソッドにする事が出来ます。
この辺りの実装のサンプルとしてはhttp://search.cpan.org/src/YAPPO/Class-Component-0.14/t/MyClass/にちゃんと真面目にテストクラス書いてるので、見てみて下さい。

もう一つは、Attributeと実際のpackage名との対応付けを変更出来るためのhook point追加です。
普通は

package Mixi;sub foo: Boofy {}
みたいなattributeを使っていたら。Boofyのattribute処理を行うpackageはMixi::Attribute::BoofyもしくはClass::Component::Attribute::Boofyになるわけですが(@ISAの中身により増える)、新しい仕組みを使うとMixi::Attribute::Bonnnuを使うように変更出来るのです。
上記の変換を実現するサンプルコードは下記の通りです。
package Mixi::Plugin;
use strict;
use warnings;
use base 'Class::Component::Plugin';

sub class_component_load_attribute_resolver {
    my($self, $attr_name) = @_;
    my $new_name = ($attr_name eq 'Boofy') ? 'Bonnu' : $attr_name;
    "Mixi::Attribute::$new_name";
}
1;

どうぞご利用下さい。

Posted by Yappo at 19:41 | Comments (0) | TrackBack

WebService::Simple::Cabinet をリリースしました。

erogeekの処女作のWebService::Simpleが普通過ぎてドン引きしていた所、これを使ったモジュールの実装アイデアを夢の中で思いついたので、起きて速攻で実装しました。

WebService::Simple::Cabinetって言います。
昨日ちょろっと作ってみた所、面白そうとブクマされたのでCPANにうpしたけどindexはまだみたい。
リポジトリはhttp://svn.coderepos.org/share/lang/perl/WebService-Simple-Cabinet/trunk/からどうぞ。

何をする物かというと、miyagawaさんがWSDL/WADLっぽいって言ってたけどWSDLとかの説明が一番しっくりきました。
WebService::Simpleを使って簡単にアクセス出来るようなAPIを更に簡単に使えるような仕組みです。
base_urlや各種パラメータ等を定義しておいて、APIを使う時に定義を読み込んで動的に必要なメソッドを作ってくれるのです。
WebService::Simple自体が非常に単純なんですが、Cabinet使えば更に簡単なメソッドでAPI叩けるようになってグーです。

書き方はmattnさんが書いてくれたlinger.plを見るとわかり易いです。
しかしこれ、一々定義YAMLをscriptに書いてあって無駄っぽいかもしれません。
本来はPlaggerのassets以下に入れられるEFTの設定ファイルみたいなとことに各種APIの定義をおいておいて、newする時に定義名を呼べば済むようにしたかったのですが、具体的に何処におけばいいかのアイデアが出てこなかったので、まだ未実装です。
WebService::Simple::Cabinet::Declare:: 以下にDSLっぽい文法で書いて置いておくアイデアもあったりします。

もともと夢の中で閃いたアイデアなので、どんな所で実用的か説明しろと問いつめられても答えに困りますが、wrapper簡単に書けたり、「なんでPerlにはLDRの購読数をwatcheするためのモジュールが無いんだよ!オレあんましそういうモジュール書けないけど欲しいんだよ!」みたいな人でもYAML書くだけでもオレオレwrapperが作れるのでいいんじゃないかなと思い始めました。

どうか皆さんでコードいじって夢の有るモジュールにしてください。

ちなみに名前の由来はmixiのmikioさんに聞いて下さい。

Posted by Yappo at 19:21 | Comments (0) | TrackBack

2008年04月03日

Class::Component 0.13 リリースのお知らせ

昨日リリースしたばっかりですが、今回はHTTP::MobileAttributeが遅いので何とかしようと色々と最適化していきました。
たとえば前回はattributeの引数を使い易くしたんですが、その解釈に文字列eval使ってて遅いので、なるべくキャッシュするようにしました。
単純にキャッシュしちゃうと不具合がある場合もあって(code ref使うときとか)その場合は、キャッシュさせないようにPlugin単位で制御出来ます。
attributeのキャッシュしないPluginには

sub class_component_plugin_attribute_detect_cache_enable { 0 }
としておいてください。

ボトルネックになっちゃってる所をごっそり書き換えたりしてるわけですが、Class::Componentはそれなりにテストを充実させてるので気楽に書き換える事が出来ました。

Class::Componentの使い方によって単純に比較出来ませんが、HTTP::MobileAttributeでは今回の最適化で6倍くらい速度が上がりました。
HTTP::MobileAttributeはそれ以外にも色々最適化が施されていて、昨日のリリースの時から比べると126倍速になってHTTP::MobileAgentより2倍遅い程度まで速くなってます。

Posted by Yappo at 18:20 | Comments (0) | TrackBack

2008年04月02日

Class::Component 0.11 リリースのお知らせ

Class::Component使ってるアプリはPluginで使える独自のAttributeを簡単に実装できるわけですが、そのときはattributeへの引数的な物が使えるのですね。

sub migi : Karada ('hikisuu') {}
ってやればhikisuuって値が取れます。
しかしこれは、引数が一つのみの場合しか想定していなくて
sub migi : Karada ('hikisuu', 'ippai') {}
ってやるとhikisuu', 'ippaiになってしまってひじょーに悲しいです。

何でかって言うと、この部分はCatalystから略な感じだったので、もうちょっと使い勝手良くしたいよ!という事で、attributeへの引数の使い勝手が良い事で有名なAttribute::Handlerから盗んできました。

こんな感じのコードが書けます。

package MyClass::Plugin::ExtAttribute;

use strict;
use warnings;
use base 'Class::Component::Plugin';


sub args_0 :Method Dump {}
sub args_1 :Method Dump('hoge') {}
sub args_1_2 :Method Dump("hoge") {}
sub args_2 :Method Dump('hoge1', 'hoge2') {}
sub args_2_2 :Method Dump('hoge1', "hoge2") {}
sub args_2_3 :Method Dump("hoge1", 'hoge2') {}
sub args_2_4 :Method Dump("hoge1", "hoge2") {}
sub args_2_5 :Method Dump(qw(hoge1 hoge2)) {}
sub args_2_6 :Method Dump(qw/hoge1 hoge2/) {}

sub ref_array_1 :Method Dump([1,2,3,4]) {}
sub ref_array_2 :Method Dump([qw/1 2 3 4/]) {}
sub ref_array_3 :Method Dump([qw(1 2 3 4)]) {}
sub ref_array_4 :Method Dump(["1",'2','3',"4"]) {}
sub ref_array_5 :Method Dump(['1', '2', '3', '4']) {}
sub ref_array_6 :Method Dump(["1", "2", "3", "4"]) {}

sub hash_1 :Method Dump(key=>'value') {}

sub ref_hash_1 :Method Dump({ key => 'value' }) {}
sub ref_hash_2 :Method Dump({ key => { key => 'value' } }) {}

sub ref_hash_array :Method Dump({ key => [qw/ foo bar baz /] }) {}

sub ref_array_hash_1 :Method Dump([ 'foo', { key => 'value' }, 'baz' ]);
sub ref_array_hash_2 :Method Dump('foo', { key => 'value' }, 'baz');

sub ref_code_1 :Method Dump(sub { return 'code' }->()) {}
sub ref_code_2 :Method Dump(sub { _code }->()) {}
sub ref_code_3 :Method Dump(sub { _code2 4, 5 }->()) {}

sub run_code_1 :Method DumpRun(sub { return 'code' }) {}
sub run_code_2 :Method DumpRun(sub { _code }) {}
sub run_code_3 :Method DumpRun(sub { _code2 4, 5 }) {}

sub _code {
    '_code';
}

sub _code2 {
    $_[0] * $_[1]
}

1;
すごいでしょ?

あとはClass::Component::PluginのPODをちょっと書き換えて、Proj::Plugin::*の各プラグインはuse base 'Class::Component::Plugin';って感じで直接Class::Component::Pluginを継承せずに、一度MyProj::Pluginを被せてから使ってね!
というポリシーに変更しました。
何でかって言うと、各モジュールごとにinitフェーズ書き換えたりとか便利メソッドをMyProj::Pluginの方に書いて便利にして欲しいからですね。
今回からattributeのパースの挙動も変更できるようになったしね。

若干Attributeの挙動を帰るため、自分が把握してる限りの所で影響でないか裏取りした後にリリースしました。
そんなわけでCPANには上げてあるので順次落とせるようになります。

Posted by Yappo at 18:34 | Comments (0) | TrackBack

2008年04月01日

I got the yapc.asia domain

まだ取れる状態だったので、いいですねーの波が来て取ってしまった。
malaに怒られないように

HTTP/1.1 307 Temporary Redirect
Location: http://conferences.yapcasia.org/ya2008/
ってやってある。
けどあとでCNAMEにしておこう。

http://yapc.asia/

Posted by Yappo at 13:03 | Comments (0) | TrackBack

転職しましたのお知らせ。

読者のみなさまへ。
お知らせです。
本日、2008年4月1日付けで、サイなんとか・ラ● へ入社しました。
学生時代からやってきたとある処理の技術を、Webという世界に応用し
たい! そんな、ここ数年やりたかったことを実現できそうな環境です。
思いっきりとある処理まわりの開発に従事したいと思います。
自分の持つ(そしてこれから得ていく)知識・技術で社会全体に何かしら
貢献できるようがんばります。
わくわく。

このリンク先と本文は関係あるかも

私といっしょにこの分野で腕をふるいたい方、ぜひご連絡ください。

Posted by Yappo at 04:01 | Comments (1) | TrackBack