我正在尝试使用以下源代码创建异步http请求客户端:
#!perl
use URI;
use DDP;
use threads;
use Thread::Queue;
use LWP::UserAgent;
use constant NUM_WORKERS => 25;
my $req_q = Thread::Queue->new();
my $res_q = Thread::Queue->new();
my @urls = ( "http://google.com", "http://web.de" );
my @workers;
for ( 1 .. NUM_WORKERS ) {
push @workers, async {
my $ua = LWP::UserAgent->new();
while ( my $req = $req_q->dequeue() ) {
$res_q->enqueue( $ua->request($req) );
}
};
}
for my $url (@urls) {
$req_q->enqueue( HTTP::Request->new( GET => $url ) );
}
$req_q->enqueue(undef) for @workers;
for ( 1 .. @urls ) {
my $res = $res_q->dequeue();
p $res;
}
$_->join() for @workers;
不幸的是我收到错误:
400 Can't locate object method "scheme" via package "URI::http"
这应该是URI
模块问题,但如果我在其他脚本中使用URI包,它可以正常工作。
我尝试将URI升级到在fedora(x86_64 GNU / Linux)perl 5.16和ubuntu(i686 athlon i386 GNU / Linux)perl 5.14上测试的URI-1.64(从1.60升级)。
e.g
$perl -MURI -E'say $INC{"URI.pm"}; say URI->VERSION; say URI->new("http://www.google.com/")->scheme'
$/home/xxxxx/perl5/lib/perl5/URI.pm
$1.64
$http
知道什么是解决问题的最佳方法?
答案 0 :(得分:3)
original code使用了Thread :: Queue :: Any而不是Thread :: Queue,因为它更好地处理对象。但是,原始代码中存在两个错误(现已修复)。
use Thread::Queue::Any 1.03 qw( );
...
my $req_q = Thread::Queue->new();
my $res_q = Thread::Queue->new();
应该是
use Thread::Queue::Any 1.03; # Must call import.
...
my $req_q = Thread::Queue::Any->new();
my $res_q = Thread::Queue::Any->new();
Thread :: Queue :: Any在import
中有效,但不应该在那里,所以我不习惯import
的习惯做法适得其反。
这些微小的更改将允许代码工作。
如果想继续使用Thread :: Queue,看起来你必须在调用use threads;
之前加载共享对象的模块(我认为这样可以节省你的记忆,所以最好这样做无论如何。)URI动态加载URI :: http,因此您需要添加
use URI::http;
或
BEGIN { URI->new('', 'http') }
之前use threads;
这会让你通过那个问题(并进入另一个问题)。