PSGI/Plackにおいて、非同期にレスポンスが返せるstreamingという仕様/機能が追加されました。
PSGI/Plack streaming is now complete

これを使うと、streamingをサポートしたサーバから非同期/nonblockingにhttpやGearmanを利用して外部へ問い合わせを行い、その結果をレスポンスしたりできます。

また、これがPlackで既に実装済みなので、非常に短いコードでサーバの実装ができちゃいます。
すばらしいですね。

すでにmiyagawaさんが、この機能を利用した非同期Web Framework「Tatsumaki」を書かれています。 イベントを扱う部分が隠蔽されているので、これを使うとさらに簡単に実装できます。
すばらしすぐる。

ここでは、簡単に外部へAnyEvent::HTTPを用いて、HTTPリクエストを行うサンプルを書いてみます。

use AnyEvent;
use AnyEvent::HTTP qw//;

$AnyEvent::HTTP::MAX_PER_HOST = 20;

my $url = 'http://localhost/tmp/sleep3.cgi';

my $hanlder = sub {
    my $env = shift;

    my $cv = AE::cv;
    AnyEvent::HTTP::http_get $url, sub {
        my $content = shift;
        $cv->send(
            [ 200, [ "Content-Type" => 'text/plain', ], [$content] ] );
    };

    return sub {
        my $start_response = shift;
        $cv->cb(
            sub {
                $start_response->( shift->recv );
            }
        );
      }
  }

PSGIのHandlerでcallbackを返し、その中でhttpアクセスからの通知を待ちます(recv)。 Any::Event::http_get でレスポンスが得られたら、配列形式のレスポンスを構築しcallbackへ通知します。

起動はplackupを利用します。

% plackup --app test.psgi --server AnyEvent port 8080

アクセス先のsleep3.cgiは3秒間のsleepしてからレスポンスを返す通常のCGIです。 なので、このサーバへアクセスすると必ず、レスポンスに3秒かかります。

% time curl http://localhost:8080/
sleep 3
curl http://localhost:8080/  0.00s user 0.01s system 0% cpu 3.052 total

では、abを利用して、平行してリクエストするとどうなるでしょう。

% time ab -c 10 -n 10 http://localhost:8080/
Concurrency Level:      10
Time taken for tests:   3.328 seconds
Complete requests:      10
Failed requests:        0
Write errors:           0
Total transferred:      720 bytes
HTML transferred:       80 bytes
Requests per second:    3.01 [#/sec] (mean)
Time per request:       3327.714 [ms] (mean) 
Time per request:       332.771 [ms] (mean, across all concurrent requests)
Transfer rate:          0.21 [Kbytes/sec] received

ここで重要なのは、3行目のこのテストにあわせてどれくらいの時間がかかっているかです。
3秒×10回の30秒ではなく、ほぼ、3秒しかかかっていません。これは10個のリクエストを非同期に処理、sleep3.cgiへのアクセスし、レスポンスを返していることで実現できています。

これだけコード量も少なくこのような機能をつくれるのはうれしいですねー。

このブログ記事について

このページは、Masahiro Naganoが2009年10月18日 23:04に書いたブログ記事です。

ひとつ前のブログ記事は「アメブロの中の人が書いたMySQLの本」です。

次のブログ記事は「WEB+DB PRESS Vol.53「大規模Webサービスの裏側」 第四回」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

ウェブページ

OpenID対応しています OpenIDについて
Powered by Movable Type 4.27-ja