代码之家  ›  专栏  ›  技术社区  ›  Mithaldu

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

  •  3
  • Mithaldu  · 技术社区  · 14 年前

    我将不得不通过简单地在一个URL上发布和获取XML来下载大量数据集。我可以通过一次执行多个请求来加快速度,但关键是:

    它需要在Windows和Linux上运行,所以 螺纹和叉子都出来了 . (因为这是纯IO绑定的,我也不认为需要它们。)

    另外,我的同事对Perl的理解不是很高,但需要能够掌握如何使用它(不一定是怎么回事,使用起来很好)。因此,如果它 API有点简单 .

    现在我在看 IO::Lambda 为了这个。

    还有其他建议吗?

    尸检: 根据德雷格顿的建议,我现在把这一点放在一起,这项工作做得很好: https://gist.github.com/661386 你可能会在CPAN Soonish上看到。

    3 回复  |  直到 14 年前
        1
  •  6
  •   draegtun    14 年前

    看看 AnyEvent::HTTP . 根据 CPAN testers platform matrix 它确实在Windows上编译和工作。

    下面是一个简单的异步发布示例( 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 @_ }
    

    铌。记住你决定要做什么 do_something_with_this 尽量避免任何 阻碍 . 见其他非阻塞 AnyEvent modules

    /I3AZ/

        2
  •  5
  •   Sinan Ünür    14 年前

    你可以试着用 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;
    

    下面是一个配置文件示例:

    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;
    

    输出:

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

    从中得到的输出将是:

    --- []

    由你来决定原因。这就是为什么 Parallel::ForkManager 允许您注册回调。就像你用的那些 AnyEvent::HTTP .

    您使用的模块是您自己的业务。只是不要一直公开地说假话。

        3
  •  1
  •   Øyvind Skaar    14 年前

    Mojo::UserAgent 也可以执行异步并行HTTP。对于非Perl人员来说,它的API可能比其他一些模块更容易理解。

    还不确定它是否符合“可靠”的条件。