Coro のメモ書き。
ボチボチ使い方をわかってきたつもりになってきたので、下記を参考にクローラの部品を書いてみたいと思います。
理解力がアレなのであれこれを一度にやるとハマるのでまずは下記の機能から。
- URL を取得するスレッドを作る
- 取得したタイトルを表示するスレッドを作る
コードはこれ。URL リストは RSS から作る。
#!/usr/bin/perl
use strict;
use warnings;
use Coro;
use Coro::LWP;
use LWP::UserAgent;
use XML::FeedPP;
my $queue = {};
my @url = ();
my @feed = (
'http://example.jp/feed',
'http://example.com/feed',
);
foreach my $url (@feed) {
my $lwp = LWP::UserAgent->new();
my $res = $lwp->get($url);
my $feed = XML::FeedPP->new($res->content);
foreach ($feed->get_item()) {
push(@url, $_->link());
}
}
# コンテンツを取得するスレッドは 100
# コンテンツを表示するスレッドは 1
create_worker( fetcher => \&fetcher, 100 );
create_worker( receiver => \&receiver, 1 );
# fetcher に URL を送りつける
queue("fetch")->put($_) for @url;
schedule;
# スレッドを作るサブルーチン
sub create_worker {
my ($name, $code, $num) = @_;
for (0 .. $num) {
my $desc = $name . "_" . $_;
async {
while( 1 ){
$code->();
}
};
}
}
# スレッド間のやりとりは Coro::Channel を使う
sub queue {
my $name = shift;
$queue->{$name} ||= Coro::Channel->new;
}
# コンテンツを取得するサブルーチン
sub fetcher {
my $url = queue("fetch")->get;
my $lwp = '';
my $res = 0;
$lwp = LWP::UserAgent->new();
$res = $lwp->get($url);
queue("receiver")->put($res->title);
}
# コンテンツを表示するサブルーチン
sub receiver {
my $receive = queue("receiver")->get;
print "$receive\n";
}
このまでは fetcher も receiver も終了せずに待機しっぱなしになりますが、理解を深める上でこんな感じにしてみました。
ロックを全くかけていないので注意。
もうちょっと勉強してまた続きを書きたいと思います。