Bazı URL'leri paralel olarak alan ve bazı işler yapan bir komut dosyası yazmam gerekiyor. Geçmişte bu tür şeyler için her zaman Parallel::ForkManager
'u kullandım, ancak şimdi yeni bir şey öğrenmek istedim ve AnyEvent
(ve AnyEvent::HTTP
veya AnyEvent::Curl::Multi
) ile eşzamansız programlama yapmayı denedim ... Ama AnyEvent'i anlamakta ve aşağıdakileri yapması gereken bir komut dosyası yazmakta sorun yaşıyorum: Belirli bir örnekte perl'de async'yi anlama
- (her satır ayrı URL) bir dosyayı açmak
- (ı yüklemek istemiyorum satırdan sonra
- okuma dosyası satırı (şu andan itibaren paralel olarak, ancak fe 10 için limitli eşzamanlı istek ile) belleğe tüm dosya - büyük olabilir)
- bir HTTP isteği oluşturmak f ya o URL
- okuma tepkisi
- güncellemeler MySQL rekor buna göre
- (sonraki dosya hat)
Ben birçok kılavuzları, öğreticiler okumak, ama onun hala sert beni engelleme ve non arasındaki farkları anlamak için - kodlama kodu. Bay Szabo temellerini açıklar http://perlmaven.com/fetching-several-web-pages-in-parallel-using-anyevent, benzer senaryo bulduk, ama hala cant gibi bir şey nasıl uygulanacağını anlıyorum:
...
open my $fh, "<", $file;
while (my $line = <$fh>)
{
# http request, read response, update MySQL
}
close $fh
...
... ve bu durumda bir eşzamanlılık sınırı ekleyin.
yardım için çok minnettar olacaktır;) Ben Net::Curl::Multi
denemeye verdi Ikegami tavsiyelerine uyarak
GÜNCELLEME
. Sonuçlardan çok memnunum. Parallel::ForkManager
'un sadece binlerce URL'yi eşzamanlı olarak yakaladığı yıllardan sonra, Net::Curl::Multi
harika görünüyor. İşte dosyamda while
döngüsündeki kodum var. Olması gerektiği gibi çalışıyor gibi görünüyor, ama ilk defa böyle bir şey yazma benim düşünceme göre daha deneyimli Perl kullanıcılarına bir göz atmak ve bazı potansiyel hatalar, kaçırdığım bir şey var mı diye bana sormak istiyorum. Ayrıca, eğer sorabilirmiyim: Net::Curl::Multi
'un eşzamanlı çalışmasının nasıl çalıştığını tam olarak anlayamadığımdan, lütfen MySQL UPDATE komutunu (DBI
aracılığıyla) RESPONSE
döngüsünün içine yerleştirme ile ilgili herhangi bir sorun beklemem gerektiğini söyleyeyim (açık bir şekilde daha yüksek sunucu yükünün yanı sıra) 50 eşzamanlı N::C::M
işçi ile çalıştırmak için komut dosyası, belki daha fazla).
#!/usr/bin/perl
use Net::Curl::Easy qw(:constants);
use Net::Curl::Multi qw();
sub make_request {
my ($url) = @_;
my $easy = Net::Curl::Easy->new();
$easy->{url} = $url;
$easy->setopt(CURLOPT_URL, $url);
$easy->setopt(CURLOPT_HEADERDATA, \$easy->{head});
$easy->setopt(CURLOPT_FILE, \$easy->{body});
return $easy;
}
my $maxWorkers = 10;
my $multi = Net::Curl::Multi->new();
my $workers = 0;
my $i = 1;
open my $fh, "<", "urls.txt";
LINE: while (my $url = <$fh>)
{
chomp($url);
$url .= "?$i";
print "($i) $url\n";
my $easy = make_request($url);
$multi->add_handle($easy);
$workers++;
my $running = 0;
do {
my ($r, $w, $e) = $multi->fdset();
my $timeout = $multi->timeout();
select $r, $w, $e, $timeout/1000
if $timeout > 0;
$running = $multi->perform();
RESPONSE: while (my ($msg, $easy, $result) = $multi->info_read()) {
$multi->remove_handle($easy);
$workers--;
printf("%s getting %s\n", $easy->getinfo(CURLINFO_RESPONSE_CODE), $easy->{url});
}
# dont max CPU while waiting
select(undef, undef, undef, 0.01);
} while ($workers == $maxWorkers || (eof && $running));
$i++;
}
close $fh;
Ben "bir sürü alıyorum geri çağırma işlevi ayarlanmamış ". URL Ana Bilgisayarında bir alanın ne zaman olduğunu gösterir. IP kullanırsam bu hatayı alamıyorum. Ayrıca, eğer koyduysam 'print 'got it!';' # işlem $ easy' ise, sayfa içeriği otomatik olarak yazdırılır. – alan
Bu nedenle, içeriğin yazdırılmasından çok, kolay bir şekilde saklanması. Geri arama hatası almıyorum?[Değişim ile deneyin. İlgili olabilir] – ikegami
Yardımlarınız için teşekkürler. Maalesef hala "geri arama işlevi ayarlanmadı" alıyorum. Aslında 4 kez, o zaman printf'in. Nereden geldiğini bilmiyorum. – alan