2013-11-23 83 views
2

我知道有很多類似這個問題的問題,但就我的研究結果而言,他們都沒有回答我的具體問題。我希望你會花時間幫助我,因爲我一直在努力尋找好幾天而沒有找到正確的答案。在Django中實現長時間運行的子進程的最佳方法?

我想找到實現一個子進程到Django應用程序的最佳方式。更具體地說:

  • 該進程將從一個視圖(異步)運行,並從另一個視圖處理。
  • 該過程可以運行長達幾個小時。
  • 同一進程/程序的多個實例應該能夠同時運行。
  • 除了知道進程何時完成(或者如果它崩潰,因此可以重新運行)之外,不需要與它進行通信。

有沒有人知道哪種方式是最好的實現呢?任何Python模塊(例如subprocess,threads,multiprocessing,spawn)能夠實現這個目標嗎?還是我必須實現一個外部任務隊列,比如Celery?

+5

我確信這可以通過其他方式實現,但是芹菜(或其他外部任務隊列)是更好的選擇。 –

+0

@LudwikTrammer謝謝!你會推薦Celery或其他外部任務隊列嗎? – Banana

+1

想想這是對芹菜的另一票。 – erewok

回答

2

如果你不想要的東西,如芹菜複雜,那麼你可以使用subprocess + nohup開始長時間運行的任務了,轉儲PID到文件(檢查如何做到這一點的subprocess文件),然後檢查如果文件中包含的PID仍在運行(使用ps)。如果你願意,你可以編寫一個非常小的'wrapper'腳本,它可以運行你告訴它的任務,如果它崩潰,寫一個'crashed.txt'文件。

有一點需要注意的是,您應該可以運行命令,包括close_fds=True值的呼叫。 (所以check_call(['/usr/bin/nohup', '/tasks/do_long_job.sh'], close_fds=True))。爲什麼?默認情況下,所有子進程都有權訪問父級的打開文件描述符INCLUDING端口。這意味着如果您需要重新啓動Web服務器進程,而長時間進程正在運行,運行進程將保持端口打開狀態,並且您將無法再次加載服務器。你可以猜到我是如何發現這一點的。 :-)

相關問題