2017-06-13 65 views
0

我在rails中創建了一個查詢資源。查詢發佈後,我使用Sidekiq在後臺創建查詢記錄並激發2個任務工作人員。
除查詢參數外,我的查詢模型還包含每個任務工作人員的狀態。在創建查詢時,每個任務的狀態都設置爲「已創建」。Sidekiq的活動記錄問題

@query = Query.create(param1: parameter1, param2: parameter2, task1_status: "created", task2_status: "created") 

Task1Worker.perform_async(@query.id) 
Task2Worker.perform_async(@query.id) 

任務1工人使用的查詢參數進行一些處理,並根據結果更新task_status要麼「已完成」或「失敗」

q = Query.find(query_id) 
status = process_task1() 
if status == SUCCESS 
    q.task1_status = "completed" 
else 
    q.task1_status = "failed" 
end 
q.save! 

任務2工人等待前完成任務1起動處理

q = Query.find(query_id) 
count = 1 
while q.task1_status == "created" 
    if count == 3 
    logger.error("Task1 state change timed out") 
    return 
    end 
    sleep(5) 
    q = Query.find(query_id) 
end 
status = process_task2() 
if status == SUCCESS 
    q.task2_status = "completed" 
else 
    q.task2_status = "failed" 
end 
q.save! 

任務1需要爲處理約4秒,並將狀態設置爲「已完成」或「失敗」。但是任務2在10秒後從未看到更新&超時,沒有處理。有什麼我在這裏失蹤。有一個更好的方法嗎?

回答

1

但任務2不會看到更新&超時後10秒,沒有處理

我懷疑緩存問題(Query.find(query_id)擊中緩存,而不是數據庫)。嘗試在每次重試時使用q.reload而不是q = Query.find(query_id)

或者,更好的是,當Task2完成時從Task1中安排Task2,這樣你就不必長時間綁定你的工作者沒有什麼

+0

第二種選擇是當然更好,OP應該試試.. –

+0

工作就像一個魅力。謝謝塞爾吉奧。 – railsnube

0

試試這個

3.times do |count| 
    logger.error("Task1 state change timed out") and return if count == 2 
    if (q = Query.find(query_id)).task1_status != 'created' 
    q.task2_status = process_task2() == SUCCESS ? 'completed' : 'failed' 
    q.save! 
    end 
    sleep(5) 
end 
+0

它應該如何幫助解決問題?更好的代碼,是的,但它做了同樣的事情,並會以相同的方式失敗 –

+0

我不知道,我發現'while q.task1_status ==「創建了」'可疑,所以直接檢查找到的對象上的'task1_status'而不是在外面聲明它並在循環內分配它..並且由於它是不可驗證的,所以不能真正重現它。 –