Mit*_*ldu 3 parallel-processing perl cross-platform download
我将不得不通过简单地在URL上发布并获取XML作为回报来下载大量数据集.我可以通过一次执行多个请求来加快速度,但这里是钩子:
它需要在Windows和Linux上运行,因此线程和分叉都会出局.(因为这纯粹是IO限制的,所以我认为它们也不需要.)
此外,我的同事并不是非常高级的perl理解,但需要能够掌握如何使用它(不一定是正在发生的事情,使用情况很好).因此,如果它的API有点简单,我会很高兴.
现在我正在寻找IO :: Lambda.
还有其他建议吗?
Post-Mortem:根据draegtun的建议,我现在把它拼凑在一起,这完美地完成了这项工作:https://gist.github.com/661386你很快就会在CPAN上看到它.
看看AnyEvent::HTTP.根据CPAN测试人员平台矩阵,它可以在Windows上编译和工作.
下面是异步POSTing(http_post)的简单示例.
use 5.012;
use warnings;
use AnyEvent::HTTP;
my $cv = AnyEvent->condvar;
my @urls = (
[google => 'http://google.com', 'some body'],
[yahoo => 'http://yahoo.com' , 'any body' ],
);
for my $site (@urls) {
my ($name, $url, $body) = @$site;
$cv->begin;
http_post $url, $body => sub {
my $xml = shift;
do_something_with_this( $name, $xml );
$cv->end;
}
}
# wait till all finished
$cv->recv;
say "Finished";
sub do_something_with_this { say @_ }
Run Code Online (Sandbox Code Playgroud)
NB.记住你决定do_something_with_this做什么,尽量避免任何阻塞.请参阅其他非阻塞AnyEvent模块
/ I3az /
您可以尝试使用LWP :: Parallel.
我只是尝试使用ActiveState的5.10.1在Windows XP上构建它,并且遇到了一些测试失败,其中一些是由于TEST脚本盲目地..在所有条目之前,@INC而其他一些似乎是由于版本与LWP::Protocol::*类不匹配.
这是一个问题.我可能会将Parallel :: ForkManager与LWP结合使用.
#!/usr/bin/perl
use strict; use warnings;
use Config::Std { def_sep => '=' };
use File::Slurp;
use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use Parallel::ForkManager;
die "No config file specified\n" unless @ARGV;
my ($ini) = @ARGV;
read_config $ini, my %config;
my $pm = Parallel::ForkManager->new(10);
my @urls = @{ $config{''}{url} };
for my $url ( @urls ) {
$pm->start and next;
my $param = [ %{ $config{$url} } ];
my $request = POST $url, $param;
my $ua = LWP::UserAgent->new;
my $fn = sprintf '%s-%s-%s.xml',
map $request->$_, qw( method uri content);
$fn =~ s/\W+/_/g;
my $response = $ua->request( $request );
if ( $response->code == 200 ) {
write_file $fn, \ $response->as_string;
}
else {
warn $response->message, "\n";
}
$pm->finish;
}
$pm->wait_all_children;
Run Code Online (Sandbox Code Playgroud)
这是一个示例配置文件:
url = http://one.example.com/search url = http://two.example.com/query url = http://three.example.com/question [http://one.example.com/search] keyword = Perl limit = 20 [http://two.example.com/query] type = Who is limit = 10 [http://three.example.com/question] use = Perl result = profit
如果您需要说服自己执行不是串行的,请尝试以下简短脚本:
#!/usr/bin/perl
use strict; use warnings;
use Parallel::ForkManager;
my $pm = Parallel::ForkManager->new(2);
for my $sub (1 .. 4) {
$pm->start and next;
for my $i ('a' .. 'd') {
sleep rand 3;
print "[$sub]: $i\n";
}
$pm->finish;
}
$pm->wait_all_children;
Run Code Online (Sandbox Code Playgroud)
输出:
[1]: a [1]: b [2]: a [1]: c [1]: d [2]: b [3]: a [3]: b [3]: c [2]: c [3]: d [2]: d [4]: a [4]: b [4]: c [4]: d
关于你对"可靠性"的评论,我认为这是错误的.您正在做的是通过以下脚本模拟的:
#!/usr/bin/perl
use strict; use warnings;
use Parallel::ForkManager;
use YAML;
my @responses = parallel_run();
print Dump \@responses;
sub parallel_run {
my $pm = Parallel::ForkManager->new(2);
my @responses;
for my $sub (1 .. 4) {
$pm->start and next;
for my $i ('a' .. 'd') {
sleep rand 3;
push @responses, "[$sub]: $i";
}
$pm->finish;
}
$pm->wait_all_children;
return @responses;
}
Run Code Online (Sandbox Code Playgroud)
你从中获得的输出将是:
--- []
由你决定原因.这就是为什么Parallel::ForkManager允许你注册回调.就像你正在使用的那些AnyEvent::HTTP.
您使用的模块是您自己的业务.只是不要继续公然虚假陈述.