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