軽量ウェブサーバ Cowboy を試す

mochiweb を仕事でも使っているので特に困っていないのですが、せっかくなので cowboy を触ってみることにしました。

ちなみに、作者の @lhoguin が来月あたり日本に来るらしく、日本の Erlang な人と会いたいと行っているので興味ある人は是非。

更新

環境と注意

Erlang: R15B02 前提です、出たばかりですが色々細かい修正がされていたりするので是非インストールしましょう。

github

今回のお試しアプリは github においてあります。

https://github.com/voluntas/snowflake/tree/feature/cowboy

動かすときはこれを前提にしています。

インストール

rebar を使っていると思いますので、rebar.config に追加して終わりです。

{deps,
  [
   {cowboy,
    ".*", {git, "git://github.com/extend/cowboy.git", {branch, "master"}}},

構成

cowboy は application:start(cowboy) で起動した後、cowboy:start_listener/6 でトランスポートとプロトコル、そして acceptor を指定する仕組みになっています。

cowboy のサンプルでは app にそのまま書かれていましたが、今回は cowboy 起動部分を独立させてみました。

-module(snowflake_cowboy).                                         

-export([start/0]).

-spec start() -> ok.
start() ->
    application:start(cowboy),
    Dispatch = [
        {'_', [
            {'_', snowflake_default_handler, []}
        ]}
    ],
    cowboy:start_http(snowflake_http_handler, 100, [{port, 8080}], [{dispatch, Dispatch}]),
    ok.

ディスパッチは {ホスト, [{パス, ハンドル名, オプション}]} のリストになっています。
今回は全部受け入れる例でにしてみました。

全てのアクセスを snowflake_default_handler に送ります。

snowflake_default_handler はただ文字列を返すだけです。

-module(snowflake_default_handler).                                

-behaviour(cowboy_http_handler).

-export([init/3, handle/2, terminate/2]).

init({_Any, http}, Req, []) ->
    {ok, Req, undefined}.

handle(Req, State) ->
    {ok, Res} = cowboy_req:reply(200, [], <<"Hello cowboy!">>, Req),
    {ok, Res, State}.

terminate(_Req, _State) ->
    ok.

Req は include/http.hrl にある http_req レコードです。
init でどのプロトコルを受け取るのか、state はどうするのかを指定します。

handle は Request が送られてきたときの処理を書きます。

behaviour で cowboy_http_handler を指定しておくと callback が指定されているので少しだけ便利です。

起動してみる

$ git clone git://github.com/voluntas/snowflake.git
$ cd snowflake
$ git checkout --track origin/feature/cowboy
$ make
$ sh start.sh

これで localhost:8080 にアクセスすれば起動が確認出来ると思います。

感想

まだソースを追いかけてないので良くわかっていませんが、URL Dispatch 周りがどう柔軟なのかが重要かなと感じています。

トランスポートとプロトコルを分けているので、SPDY 対応とかも出来ると言えば出来るかも知れません。

軽量かどうかの負荷試験は誰かにお任せしておきます。

まだまだ発展途上ではありますが、押さえるところは押さえているフレームワークだなと感じました。