Coro::Channelをつかってみた

use Plack::Request;
use HTTP::Request;
use Data::Dumper;
use Coro;
use Coro::Channel;
use Coro::AnyEvent;
use Coro::LWP;
use LWP::UserAgent;


# worker threads
sub build_channel {
    warn "[$$] build channel";
    my $channel = Coro::Channel->new();
    for my $i (0..100) {
        async {
            while(1) {
                my $req = $channel->get();
                my $ua = LWP::UserAgent->new();
                my $res = $ua->request($req->[0]);
                my @res_header;
                $res->headers->scan(sub{
                    push @res_header, @_;
                });
                $req->[1]->send([
                    $res->code,                    \@res_header,
                    [$res->content]
                ]);
            }
        }
    }
    return $channel;
}

my $channel;
my $hanlder = sub {
    my $env = shift;
    my $req = Plack::Request->new($env);

    $channel ||= build_channel();

    my $request = HTTP::Request->new(
        $env->{REQUEST_METHOD},
        URI->new_abs($env->{REQUEST_URI},'http://localhost/'),
        [
            map {
                (my $field = $_) =~ s/^HTTPS?_//;
                ( $field => $env->{$_} );
            }
            grep { /^(?:HTTP|CONTENT|COOKIE)/i } keys %$env
        ],
        $req->raw_body
    );

    my $cv = AE::cv;
    $channel->put( [$request,$cv ] );

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

created by blog.nomadscafe.jp

コメント

コメントはありません

コメントを投稿

コメントを投稿するにはログインが必要です