簡體   English   中英

單擊按鈕僅運行一次celery任務

[英]run celery task only once on button click

我創建了一個celery任務來組織數據庫表的django應用。 芹菜任務大約需要8秒鍾來完成這項工作(相當多的表移動和超過100萬行的查找)

此芹菜通過注冊用戶單擊按鈕開始。

我在views.py中創建了一個任務視圖,並在urls.py中創建了一個單獨的task-url。 導航到此任務URL時,任務開始。

我的問題:

  1. 在任務未完成時刷新任務URL時,將啟動新任務。
  2. 通過此設置,您可以導航到另一個頁面或重新加載視圖

如何防止每次刷新時啟動任務,並防止導航到另一個頁面。 理想情況下,用戶只能運行此特定類型的一項任務。

可以在JQuery / Ajax中實現嗎? 因為我不是專家,也沒有使用JQuery / Ajax的經驗,所以有些英雄可以向我指出正確的方向。

謝謝

“如何防止每次刷新時啟動任務”

首先,請確保使用“ POST / redirect / GET”模式:您的視圖應僅在“ POST”請求上觸發任務(GET請求必須沒有副作用),然后返回HttpResponseRedirect

這不會阻止用戶在第一個任務仍在運行時觸發第二個任務,但確實可以防止每次刷新(“ GET”)頁面時重新提交表單...

理想情況下,用戶只能運行此特定類型的一項任務。

觸發任務時,將其ID存儲在會話中,並觸發任務之前檢查會話中的任務ID。 如果有,請使用它檢查任務的狀態。 如果完成(無論結果如何),請刪除任務ID並繼續執行新任務,否則僅顯示一條消息,告訴您用戶他已經在運行任務。

只要確保您在會話中正確處理了“幽靈” task_id的情況即可(這可能是一個長期完成的任務,芹菜已經放棄了該結果,或者是一個因工人或經紀人崩潰而迷失的任務-是的,噓! t發生-等等)。 一個(timestamp, task_id)解決方案是實際存儲(timestamp, task_id)對,並且如果celery沒有task_id的狀態-實際上“無狀態”被命名為celery.states.PENDING ,這實際上意味着“我沒有一個有關此任務的狀態ATM的線索”-檢查時間戳記。 如果它比它應有的年代久遠,那么您可能會認為它已經死了而且在6英尺以下。

並防止導航到另一個頁面。

實際上,您為什么要阻止您的用戶執行其他操作? 從UI / UX的角度來看,一旦任務被觸發,您的用戶應被重定向到“請稍候”頁面,並(盡可能)帶有一些進度條或類似的反饋。 這里的簡單(如果有點繁瑣)的解決方案是使用ajax進行一些輪詢:您設置一個接受task_id的視圖,檢查結果/進度,並將其返回為json,然后“請等待”頁面調用此視圖(使用ajax )每隔X秒更新一次(可能會在完成任務后將用戶重定向到下一頁)。

現在,如果有一些操作(除了重新啟動同一任務),而用戶在任務運行時無法執行,則可以對這些操作使用相同的“檢查當前任務的會話”機制(將其作為視圖裝飾器確實有幫助)。

我相信使用鎖可以在服務器端更輕松地完成此操作,請參見此問題。 用芹菜運行“獨特”任務

如果需要在客戶端完成,可能的方法是像這樣設置cookie

if (typeof $.cookie("running") === "undefined"){
  var date = new Date();
  var minutes = 20;
  date.setTime(date.getTime() + (minutes * 60 * 1000));
  $.cookie("running", "true", { expires: date });
}

並在任務完成時刪除

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM