[英]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.