この記事は Perl 6 Advent Calendar 2015 の1日目です。
Perl 6 は、2015年のクリスマスにリリースされることになっており、我々としてはそれを待ち受ける必要があると考えました。
Perl6 がリリースされた暁には、いろいろ遊ぼうかなという気持ちをみなさんお持ちだと思います。 Perl6 には夢が詰まっており、様々な機能が含まれている夢の言語です。
そういった、夢の機能については今後、クリスマスまでの間に、語られていきますが、本稿では、現実的な話をします。
今年のクリスマスに Perl6 がリリースされるぞ、という宣言がでたわけですが、そうなってくると、Perl6 をクリスマスから早速遊びたいなと思うわけですよね。
そして、私は web engineer なので、 Perl6 が出たら早速 web application を書きたいと思うわけです。
しかし、そこで気づいてしまう。Perl6 には Plack のようなものが無いと!
Perl6 に Plack のようなものがないし、当時まともな httpd の実装が存在していなかったのです! (実際には存在はしていたのですが、multi thread 対応していないし、なぜか当時の MoarVM は listen の backlog が 1 にハードコードされているためにまったく実用的ではなかったのです。この listen のバックログがハードコードされている問題は現在では修正されています)
これではいけない。と気づくわけです。まともな httpd が必要だ。
とりあえず fork(2)
があれば、listen backlog が 1 にハードコードされているというハードな環境下でもなんとかなるだろうと思って、まず NativeCall ( Perl6 から FFI で C 関数をコールする機能) を使って fork を呼ぶようにしてみました。これはなかなかうまく動作したのですが、Mac で動作しないという問題が発見されました。
なぜか。
MoarVM は内部で libuv を利用しており、あらゆるソケット処理に libuv を利用しています。 libuv は fork をサポートしていません。より具体的に言うと mac の kqueue は fork をサポートしてないので、完全に詰みました。
対策として、ソケットライブラリを全部 NativeCall で実装することも考えたのですが(実装もしたのですが)、完全に本質を見失っている感じがしてきたので、この方針は諦めることにしました。
そうこうしているうちに、IO::Socket::Async ベースならわりと動くっぽいのではないかという話になり、IO::Socket::Async ベースで実装する方針に転換しました。
何度か書き直したのですが、まあそこそこ動くようになりました。
そのそこそこ動く実装が HTTP::Server::Tiny です。これは Perl5 の有名な httpd 実装である kazuhooku 氏による Starlet を参考に実装されており、HTTP/1.1 に対応した高速なサーバーです。 (Perl6 でできる範囲としてはかなり高速になるように実装しています。期待したパフォーマンスが出ていなければ、それは、、)
https://github.com/tokuhirom/p6-HTTP-Server-Tiny/
そういうわけで、HTTP::Server::Tiny ができたので、あとは Plack 相当のレイヤーを実装しようということになりました。
そこで、下記12名の Perl Monger が集まり、Plack を Perl6 に移植するプロジェクトに乗り出しました。
https://github.com/tokuhirom/p6-Crust
結果として、2015年12月1日時点でほぼ Plack の機能を実装しております。 例えばイカのように実行すれば、さくっと httpd が立ち上がります。めっちゃ便利。
crustup -e 'sub { 200, [], ["OK"] }'
具体的にはイカのものが完備されています。
そんなわけで、ウェブアプリケーションをかく準備は整っています。
あとは Perl6 のリリースを待つだけや!!!!
明日は karupanerura さんの 無限リストであそぶ です。