我有一個簡單的sidekiq工作,我已經設置使用發條每5分鐘運行一次。我擔心的是,如果工作時間超過5分鐘,它將再次運行,如果它與原工作同時運行,可能會導致一些問題。如何確保同一份工作不會同時運行兩次?
有沒有辦法鎖定發條,使其僅在上次運行完成時才能運行?
我有一個簡單的sidekiq工作,我已經設置使用發條每5分鐘運行一次。我擔心的是,如果工作時間超過5分鐘,它將再次運行,如果它與原工作同時運行,可能會導致一些問題。如何確保同一份工作不會同時運行兩次?
有沒有辦法鎖定發條,使其僅在上次運行完成時才能運行?
一個選項是在作業開始時創建包含進程PID的文件,並在作業結束時將其刪除,如果PID文件已存在,則在開始時中止作業。
雖然我的應用程序的這個特定部分沒有使用sidekiq,但這個想法是一樣的。以下是我的應用程序如何執行此操作:https://github.com/WikiEducationFoundation/WikiEduDashboard/blob/master/lib/data_cycle/constant_update.rb
這並不保證工作是唯一的,因爲Sidekiq可以跨多個節點同時運行,因此根據哪個節點運行作業,作業可能會或可能不會被觸發。由於Sidekiq需要Redis,更好的解決方案是使用Redis作爲數據存儲。一個例子是https://github.com/kenn/redis-mutex。 – anothermh
Sidekiq允許您通過API查詢隊列。
當您的任務運行時,您可以簡單地查詢sidekiq隊列。檢查隊列和/或作業是否仍然存在。如果是,則什麼都不要做。如果不是,則排隊工作。
我不知道你的工作是否在一個單獨的隊列中,這可能是最好的。這樣您可以查看隊列大小,如果它是0,則啓動另一個進程。
我使用Sidekiq Unique Jobs gem做到這一點。它有防止重複工作的各種策略。
這款Gem是否需要Sidekiq Enterprise或是完全獨立的Gem? –
另外,我相信這個寶石不適用於ActiveJob。 –
Sidekiq Enterprise包括支持unique jobs。獨特的作業與工人階級的選項定義:
# app/workers/my_worker.rb
class MyWorker
include Sidekiq::Worker
sidekiq_options unique_for: 10.minutes
def perform(...)
end
end
他們必須在Sidekiq初始化啓用,以及:
# config/initializers/sidekiq.rb
Sidekiq::Enterprise.unique! unless Rails.env.test?
的時間窗口只有作業運行時適用,例如,如果它在10分鐘內是唯一的並且在6分鐘內完成工作,那麼Sidekiq將立即允許其他工作排隊;您不必再等4分鐘才能刪除唯一性鎖。
跨所有Sidekiq Enterprise節點實施唯一性約束。
您可能需要調整retries
選項,因爲失敗的作業只要處於重試狀態就會繼續保持鎖定狀態。 (即使它沒有正在執行)
如果您不想購買Sidekiq企業版,它具有獨特的作業支持,您可以在作業運行時使用redis中的密鑰進行存儲,並刪除密鑰一旦工作完成。僅當密鑰不存在時才排隊工作 –