Появился ещё один вариант:
| Код | #!/usr/bin/perl use warnings; use strict;
use HTTP::Request; use POE qw(Component::Client::HTTP Component::Client::Keepalive);
my %config = (jobs_max => 100, delay => 10);
my %data = (domains => load('domains.txt'));
our $debug = 'yes';
my $pool = POE::Component::Client::Keepalive->new( 'keep_alive' => 300, 'max_open' => 1000, 'max_per_host' => 10, 'timeout' => 20, );
POE::Component::Client::HTTP->spawn( 'Alias' => 'HTTP_CLIENT', 'MaxSize' => 300000, 'Timeout' => 300, 'Agent' => 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)', 'Streaming' => 0, 'FollowRedirects' => 0, 'ConnectionManager' => $pool );
POE::Session->create( 'inline_states' => { '_start' => \&_sess_start, '_stop' => \&_sess_stop, 'get_jobs' => \&_get_jobs, 'job_done' => \&_job_done, }, 'heap' => { config => \%config, data => \%data, } );
POE::Kernel->run;
sub _sess_start { my ($kernel, $heap) = @_[KERNEL, HEAP]; debug("_sess_start: STARTED\n"); $kernel->yield('get_jobs'); }
sub _sess_stop { my ($kernel, $heap) = @_[KERNEL, HEAP]; debug("_sess_stop: STOPPED\n"); }
sub _get_jobs { my ($kernel, $heap) = @_[KERNEL, HEAP]; my $config = $heap->{config}; my $data = $heap->{data}; if (($difference == $config->{jobs_max}) && (scalar(@{$data->{domains}}) == 0)) { $kernel->delay('get_jobs', $config->{delay}); } my $difference = $config->{jobs_max} - $kernel->call('HTTP_CLIENT' => 'pending_requests_count'); debug("_get_jobs: DIFFERENCE $difference\n"); if ($difference <= 0) { debug("_get_jobs: RETURN\n"); return; }
my @jobs = splice(@{$data->{domains}}, 0, $difference); foreach my $job (@jobs) { my $request = HTTP::Request->new(GET => "http://".$job."/"); $kernel->post('HTTP_CLIENT' => 'request', 'job_done', $request); } debug("_get_jobs: ADDED ".scalar(@jobs)."\n"); debug("_get_jobs: REMAINS ".scalar(@{$data->{domains}})."\n"); }
sub _job_done { my ($request_packet, $response_packet) = @_[ARG0, ARG1]; my $request = $request_packet->[0]; my $response = $response_packet->[0]; debug("_job_done: ".$response->code."(".$1.")\n") if $response->base =~/^http:\/\/([a-z0-9-\.]+)\//; open(FILE, ">pages/[".$response->code."]-$1.html"); print FILE $response->content; close(FILE); }
sub debug { print @_ if $debug eq 'yes'; }
sub load { my $file = shift; my @domains = (); open(FILE, $file) || return undef; while (<FILE>) { chomp(); push(@domains, $_); } close(FILE); return \@domains; }
|
Подскажите какой принцип лучше использовать : 1. Создать 1 сессию и в ней пачками получать и отрабатывать запросы (код тут). 2. Создать множество сессий равное количеству запросов (код в первом посте).
Сам склоняюсь к первому.
Почему оба кода на linux CentOS 5 (This is perl, v5.10.0 built for i386-linux-thread-multi) отрабатывают правильно, а на Windows 7 (This is perl, v5.10.1 built for MSWin32-x86-multi-thread) большая часть приходит с ошибкой 500 =( |