0

我目前在Sidekiq-Unique-Jobs和Sidekiq-Status的幫助下使用Sidekiq在我的應用程序上執行任務。Rails 4 Racing/Concurrency。避免死鎖

工作人員執行的工作量很小,幾乎總是立即執行。 (很少或根本沒有隊列)

我是「黑客」sidekiq同步執行任務(檢查Controller can't find object created by worker),這些工作是小而快的執行(通常少於1秒)。而我的應用程序需要同步運行的作業並獲得其詳細信息(創建/更新記錄)

隨着「跛腳」的解決辦法,我使用:

20.times do 
    status = Sidekiq::Status::get balance, :exp_status 
    if ["done"].include?(status) 
     break 
    end 
    sleep(0.2) 
    end 

創建隊列,並通過PARAMS保證(sidekiq-唯一的工作),同一用戶同時執行不超過1個工作,我可以避免所有的死鎖,但我認爲它應該是一個更好的方法來執行此操作,而不是黑客攻擊sidekiq,因爲它意味着異步執行作業。

問題是:是否有任何替代或相似的gem到sidekiq的方式,我可以限制輸入但缺省情況下,這意味着要同步運行?我不能僅僅詢問控制器Balance.find_or_create_by(user: user, market: market),因爲它遲早會給我造成死鎖(記錄被同時編輯/操作/創建),但我覺得我使用的這個sidekiq解決方案在長期方面也不好。我是否缺少基本的東西?如何通過中間件或類似的東西來確保重複的params/action不會同時執行以避免死鎖?

+0

您的死鎖是來自sidekiq,還是您的_database_?或者是其他東西?你是什​​麼意思,「因爲它遲早會給我造成僵局」 - 當它發生時,這看起來是什麼樣子?你從某個東西得到一個錯誤信息?你會得到你不想要的行爲? (後者可能不是「僵局」,但可能是一種競爭條件)。如果這涉及您的數據庫競爭條件,則有一套技術;如果真的存在僵局,那麼還有另外一個。我認爲你所要求的不完全是你想要的,但是如果你解釋你實際上想要做什麼以及爲什麼它失敗了。 – jrochkind

回答

2

我解決我的問題Redis-Mutex

有了這個,我有一個本地同步解決方案,仍然可以鎖定我正在處理的行,並且在鎖定行的情況下沒有問題,因爲我正在用簡單的重試進行救援。當記錄解鎖時,它會回來並重試該工作

def enter 
    RedisMutex.with_lock(user) do 
     # hard-work 
    end 
    rescue RedisMutex::LockError 
    retry 
    end