2014-09-04 66 views
2

我有一个perl脚本来检查数据库是否有内部API调用请求。什么是与perl同时连接多个URL的最佳方式

当它看到一个,它使用LWP根据请求调用API。

问题是,有时这些请求可能需要一段时间才能完成,而其他请求在它们后面排队。我正在设法制定防止这种情况的最佳方法。

该脚本相对简单。我简要地看了一下POE和AnyEvent,但一直没能找到任何帮助我理解在这种情况下如何使用它们的教程。看起来他们主要是为了更复杂的情况而设计的。

在简化的,我的半伪代码是:

while (1) { 
    $url=getNextRequestFromDB(); 
    if ($url ne "") { 
     $request = new HTTP::Request('GET', $url); 
     my $response = $ua->request($request); 
     logResponse($response); 
    } 
    else { 
     sleep(5); 
    } 
} 

如果响应没有登录,或者如果它被单独地记录(优选地)我不介意。

回答

2

该CPAN模块LWP::Parallel符合您正在寻找的要求。它需要一个URL列表(支持http,ftp和文件URL),并行连接它们,然后等待结果。

+0

这看起来很有趣,但我不确定它会对此有所帮助。例如,如果我在循环1中获得了4个请求,并且请求#1花了5分钟,那么在循环2启动之前还有5分钟,因此如果在代码调用'$ pua-> wait'之后进入另一个请求,它在当前的4个请求完成之前仍然会卡住。 – 2014-09-04 17:56:37

1

要在perl程序中并行执行长时间运行的操作,请使用fork()或线程库。

fork是一个子进程,它最初继承了所有程序状态的一个副本,然后是独立的。每个叉需要一个自己的数据库连接。

fork()返回当您处于程序的父项副本中时新创建的子进程ID,当您处于子进程时返回false。

# create 10 children 

my @children; 

for (my $count = 1; $count <= 10; $count++) { 
     my $pid = fork(); 
     if ($pid) { 
     # you are in the parent process 
     # print "child has $pid, parent $$\n"; 
     push(@children, $pid); 
     } elsif ($pid == 0) { 
        # You are in the child 
       while (1) { 
        ## Connect to the DB 
        ## fetch an api request 
        ## last if $no_request_left 
        ## run an api request 
       } 
       ## disconnect from DB 
       ## cleanup whatever needs to be done, then exit 
       exit 0; 
     } else { 
       die "couldnt fork: $!\n"; 
     } 



} 

foreach (@children) { 
     my $tmp = waitpid($_, 0); 
     print "pid $tmp found no more requests and exited\n"; 

} 

print "Main ends here\n"; 
+0

如果我理解正确,那么您在这里有10个分支,每个分支运行我的整个过程。无法将db连接移出分支,以便每次找到请求(而不是您的示例中的for循环)时,它会分叉执行API调用,然后记录响应并退出?那么就不需要更多的数据库连接。 – 2014-09-04 06:51:54

+0

这不起作用。叉提供需要自己的数据库连接的子进程。如果您需要在子项之间共享数据库连接,则需要在父项中建立连接,并为所有请求实施与父项的进程间通信,或者使用线程代替。分叉数据库连接通常会过时。 – user4004936 2014-09-04 07:01:14

+0

附录:您可以重新设计此工作流程:请父母完成所有数据库工作,从数据库获取api调用或合理的短列表/调用数组,创建子项,获取下一批次,创建下一个子项。每个孩子都会处理它的清单,然后终止。 – user4004936 2014-09-04 07:02:59

0

看看Mojo::UserAgent。他们在链接文档中有并发请求的例子。

相关问题