[英]How do I make parallel HTTP requests in Perl, and receive them back in order?
[英]How do I make 25 requests at a time with HTTP::Async in Perl?
我正在做很多HTTP请求,我选择HTTP :: Async来完成这项工作。 我有超过1000个请求,如果我只是执行以下操作(请参阅下面的代码),许多请求在处理时会超时,因为在处理它们之前可能需要几十分钟:
for my $url (@urls) {
$async->add(HTTP::Request->new(GET => $url));
}
while (my $resp = $async->wait_for_next_response) {
# use $resp
}
所以我决定每次做25个请求,但我想不出用代码表达它的方法。
我尝试了以下方法:
while (1) {
L25:
for (1..25) {
my $url = shift @urls;
if (!defined($url)) {
last L25;
}
$async->add(HTTP::Request->new(GET => $url));
}
while (my $resp = $async->wait_for_next_response) {
# use $resp
}
}
然而这并不好用,因为它现在太慢了。 现在它等待所有25个请求都被处理,直到它再添加25个。所以如果它还有2个请求,它什么都不做。 我要等待处理所有请求以添加下一批25。
我如何改进这种逻辑,使$async
在处理记录时做一些事情,同时也确保它们不会超时。
如果你不能足够快地调用wait_for_next_response
,因为你正在执行其他代码,最简单的解决方案是通过将代码移动到一个单独的执行线程来使代码可中断。 但是如果你要开始使用线程,为什么要使用HTTP :: Async?
use threads;
use Thread::Queue::Any 1.03;
use constant NUM_WORKERS => 25;
my $req_q = Thread::Queue::Any->new();
my $res_q = Thread::Queue::Any->new();
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();
...
}
$_->join() for @workers;
你很亲密,你只需要结合这两种方法! :-)
未经测试,因此将其视为伪代码。 特别是我不确定total_count
是否是正确的使用方法,文档没有说明。 您还可以在添加请求时使用$active_requests
++
$active_requests
计数器,并且--
当您收到响应时。
while (1) {
# if there aren't already 25 requests "active", then add more
while (@urls and $async->total_count < 25) {
my $url = shift @urls;
$async->add( ... );
}
# deal with any finished requests right away, we wait for a
# second just so we don't spin in the main loop too fast.
while (my $response = $async->wait_for_next_response(1)) {
# use $response
}
# finish the main loop when there's no more work
last unless ($async->total_count or @urls);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.