2014-11-23 20 views
1

一個長期運行的Python函數這裏的粗糙的工作流程:運行從Django的

Request for a job comes in to a particular view -> Job entered in Database -> requestProcessor() launched independent of current process -> Response "Job has been entered" is returned instantly -> 

requestProcessor()查看數據庫,如果有要處理任何未完成的作業看,並開始處理它。需要大約3小時才能完成。

我很長時間以來對這個問題感到困惑。我應該使用multiprocessing.Poolapply_async?我沒有多個流程的經驗,所以我不確定最好的方法是什麼。

回答

0

你應該可以很容易地做到這一點。這可以用Celery(見Iain Shelvington's answer)。要回答你關於多模塊是如何工作的問題,但是,你也可以簡單地做這樣的事情:

from django.shortcuts import render 
from multiprocessing import Process 
import time 

def do_job(seconds): 
    """ 
    This is the function that will run your three-hour job. 
    """ 
    time.sleep(seconds)      # just sleep to imitate a long job 
    print 'done!'       # will go to stdout, so you will see this 
              # most easily in test on local server 

def test(request): 
    """ 
    This is your view. 
    """ 
    # In place of this comment, check the database. 
    # If job already running, return appropriate template. 
    p = Process(target=do_job, args=(15,)) # sleep for 15 seconds 
    p.start()        # but do not join 
    message = 'Process started.' 
    return render(request, 'test.html', 
        {'message': message}) 

如果您在本地測試服務器上運行它,你會立刻被帶到測試頁,然後在你的stdout你會看到done!在15秒後顯示。

如果您要使用類似的東西,您還需要考慮在作業完成時是否需要通知用戶。此外,您需要考慮是否在第一份工作完成前阻止進一步的工作請求。我不認爲你會希望用戶能夠隨意啓動500個進程!你應該檢查你的數據庫進程,看看作業是否已經在運行。

+0

這和'pool = Pool(processes = 1)有什麼區別?結果= pool.apply_async(myfunction)'方法?考慮到我正在調用一個Python函數本身,這似乎更方便一些。 – user1265125 2014-11-23 13:45:18

+0

@ user1265125「池」用於工作進程池。我相信你在這裏只需要一個過程。那是對的嗎?你的描述表明這可能是一種行政型工作。我的答案中的方法還調用了一個python函數(我已經任意命名爲'do_job')。 – 2014-11-23 13:47:49

+0

如果經常調用視圖,這將導致發生無法控制的進程增長。 – 2014-11-23 13:50:00

2

Celery是實現這種確切類型的功能的偉大工具。你可以使用它了 「任務隊列」,例如:

tasks.py

from celery import task 

@task 
def do_job(*args, **kwargs): 
    """ 
    This is the function that does a "job" 
    """ 
    # TODO: Long running task here 

views.py

from django.shortcuts import render_to_response 

from .tasks import do_job 

def view(request): 
    """ 
    This is your view. 
    """ 
    do_job.delay(*args, **kwargs) 
    return render_to_response('template.html', {'message': 'Job has been entered'}) 

調用.delay會被你的芹菜一名工人註冊do_job執行但不會阻止視圖的執行。一個任務不會被執行,直到工人變得自由,所以你不應該對這種方法產生的進程數量有任何問題。