什么是目前最舒适,最可靠的跨平台Perl模块进行并行下载?

时间:2010-11-03 10:58:11

标签: perl cross-platform download parallel-processing

我将不得不通过简单地在网址上发布并获取XML作为回报来下载大量数据集。我可以通过一次执行多个请求来加快速度,但这里有钩子:

它需要在Windows和Linux上运行,因此线程和分支都是。 (由于这纯粹是IO限制的,我认为它们也不需要。)

此外,我的同事并没有达到非常高的perl理解水平,但需要能够掌握如何使用它(不一定是正在发生的事情,使用情况很好)。因此,如果 API有点简单,我会很高兴。

现在我正在考虑IO::Lambda

还有其他建议吗?

死后事件:根据draegtun的建议,我现在把它拼凑在一起,完美地完成了这项工作:https://gist.github.com/661386你很快就会在CPAN上看到它。

3 个答案:

答案 0 :(得分:6)

看看AnyEvent::HTTP。根据{{​​3}}它确实编译&在Windows上工作。

以下是异步POST(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 @_ }

NB。请记住,do_something_with_this尝试避免任何阻止的任何内容。请参阅其他非阻止CPAN testers platform matrix

/ I3az /

答案 1 :(得分:5)

您可以尝试使用LWP::Parallel

更新

我只是尝试使用ActiveState的5.10.1在Windows XP上构建它并遇到一些测试失败,其中一些是由于TEST脚本盲目地将..添加到{{1}中的所有条目和其他人似乎是由于版本与@INC类不匹配。

这是一个问题。我可以将Parallel::ForkManagerLWP一起使用。

LWP::Protocol::*

以下是配置文件示例:

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 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;

输出:

[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;

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;

您从中获得的输出将是:

--- []

由您决定原因。这就是#!/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; } 允许您注册回调的原因。就像您使用Parallel::ForkManager时那样。

您使用的模块是您自己的业务。只是不要继续公然虚假陈述。

答案 2 :(得分:1)

Mojo::UserAgent也可以做async paralell http。对于非perl人来说,它的API可能比其他一些模块更容易理解。

不确定它是否符合“可靠”的要求..