Coro::LWPでtimeout + timeoutきりかえ

Coro::LWPでタイムアウトさせるに加えて、1つのasyncの中で複数回LWPを行ない、それぞれのtimeout、on_destory時の挙動を変更するtest


何がやりたいかというと

A->B->C

というリクエスと順は保ちつつ、それぞれを非同期でアクセスするものです

proxyっぽいものを実装する際に、Aで認証、Bで実際のアクセス、Cでフィルタ動作

を狙ってます。

use Time::HiRes;
use Coro;
use Coro::LWP;
use LWP::UserAgent;
use Data::Dumper;

sub coro_timeout {
    my $timeout = shift;
    my $cb = shift;
    my $coro = $Coro::current;
    $coro->{timeout_at} = Time::HiRes::time() + $timeout;
    my $installed_destroy = $coro->{on_destroy_once} ? 1 : 0;
    $coro->{on_destroy_once} = $cb;
    if ( !$installed_destroy ) {
        $coro->on_destroy( sub {
            my $message = shift;
            my $cb = delete $coro->{on_destroy_once};
            return unless $cb;
            return if $message ne 'timeout';
            $cb->($message);
        });
    }
}

my $parent_loop = 0;
for my $timelimits ( [10,10,10],[1,10,10],[10,1,10],[10,10,1] ) {
    $parent_loop++;
    my $parentloop = $parent_loop;
    async {
        $Coro::current->desc("LWP");
        my $childloop = 0;
        for my $timelimit ( @$timelimits ) {
            $childloop++;
            my $ua = LWP::UserAgent->new;
            coro_timeout($timelimit, sub {
                 my $message = shift;
                 warn sprintf "parent: %s, child: %s cancel because %s", $parentloop, $childloop, $message;
            });
            my $res = $ua->get("http://localhost/tmp/sleep3.cgi");
            warn "parent: $parentloop, child: $childloop done!";
        }
        warn "parent: $parentloop done all!";
    };
}

my $w; $w = AnyEvent->timer (
    after => 0.5,
    interval => 1,
    cb => sub {
        my $now = Time::HiRes::time;
        my @lwp_coro = grep { $_->desc eq "LWP" } Coro::State::list;
        for my $coro (@lwp_coro) {
            if ($now > $coro->{timeout_at}) {
                $coro->cancel("timeout");
            }
        }
        if (@lwp_coro == 0) {
            exit;
        }
    }
);

schedule;

実行結果

% perl coro_lwp.pl
parent: 2, child: 1 cancel because timeout at coro_lwp.pl line 41.
parent: 4, child: 1 done! at coro_lwp.pl line 44.
parent: 3, child: 1 done! at coro_lwp.pl line 44.
parent: 1, child: 1 done! at coro_lwp.pl line 44.
parent: 3, child: 2 cancel because timeout at coro_lwp.pl line 41.
parent: 4, child: 2 done! at coro_lwp.pl line 44.
parent: 1, child: 2 done! at coro_lwp.pl line 44.
parent: 4, child: 3 cancel because timeout at coro_lwp.pl line 41.
parent: 1, child: 3 done! at coro_lwp.pl line 44.
parent: 1 done all! at coro_lwp.pl line 46.
created by blog.nomadscafe.jp

コメント

コメントはありません

コメントを投稿

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