2014-09-04 48 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。他們在鏈接文檔中有併發請求的例子。

相關問題