2013-07-25 56 views
3

我想要一個Mojolicious應用程序的請求,以便能夠觸發長時間運行的作業。客戶不需要等待這麼長時間的工作才能完成,所以我希望應用程序能夠快速回復並開始工作。下面是我的想法:我該如何強制Mojolicious向客戶發送回覆?

use Mojolicious::Lite; 
get '/foo' => sub { 
    my $self = shift; 
    $self->render(text => 'Thanks for requesting /foo. I will get started on that.'); 
    # ... force Mojolicious to send response now ... 
    do_long_running_job(); 
}; 

但是,當我寫這樣的代碼,客戶端沒有收到長時間運行的作業完成後,直到響應(這可能會引發不活動超時等)。有什麼方法可以更快地發送回覆?是否有另一種方式來構建我的代碼/應用程序來實現這一目標?從文檔

的事情,看起來很有前途,但沒有奏效:

$self->rendered(200); 
$self->res->finish; 
+1

這是因爲它不發送,直到'sub'返回?如果是這樣,作爲一個猜測,如果你'fork',它會工作,父母返回「謝謝...」,孩子繼續與'do_long_running_job()'? – chrsblck

+0

恕我直言,最簡單的方法是使用websockets ... – jm666

回答

2

蘭德爾·施瓦茨的Watching long processes through CGI應該有所幫助:

的孩子去上,但它必須首先關閉STDOUT,否則Apache會認爲瀏覽器可能仍會有一些輸出,並且在這一切都解決之前,不會響應瀏覽器或釋放連接。接下來,我們必須啓動孩子的子進程來執行…

我們將在第37行用一個包含隱式分支的管道打開來完成此操作。孫級進程將STDERR合併到STDOUT,然後執行…

孩子(也就是traceroute的父親)從STDOUT(和STDERR)&hellip打開的文件句柄中讀取;

簡而言之,子進程會執行命令。 …

鑑於您只關心啓動進程而不是看它,您應該能夠修剪大部分代碼。

+0

'叉'+'關閉STDOUT'看起來它會做的伎倆 - 謝謝 – mob

相關問題