Rails 4 Racing / Concurrency。 避免死锁

我目前在Sidekiq-Unique-Jobs和Sidekiq-Status的帮助下使用Sidekiq在我的应用程序上执行任务。

工人执行的工作很小,几乎总是立即执行。 (很少或根本没有队列)

我正在“黑客攻击”sidekiq同步执行任务(检查Controller无法找到工作人员创建的对象 ),这些作业很小且执行速度快(通常不到1秒)。 我的应用程序需要同步运行作业并获取其详细信息(记录创建/更新)

随着我使用的“跛脚”解决方案:

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

创建一个队列并确保通过params(sidekiq-unique-jobs)同一个用户同时执行不超过1个作业我可以避免所有死锁,但是我觉得它应该是一个更好的方法来执行此操作,而不是黑客sidekiq因为它意味着异步执行作业。

问题是 :对于sidekiq是否有任何替代或类似的gem可以限制输入但是默认情况下是同步运行的? 我不能只问控制器Balance.find_or_create_by(user: user, market: market)因为它迟早会给我死锁(记录被同时编辑/操纵/创建)但我觉得这个sidekiq解决方案我从长远来看,使用也不行。 我错过了一些基本的东西吗? 如何确保通过中间件或类似的东西不会同时执行重复的参数/动作以避免死锁?

你正在乱砍一个穷人的分布式互斥锁。 有更好的方法。

FOSS

Sidekiq Enterprise的官方API

我用Redis-Mutex解决了我的问题。

有了这个,我有一个本机同步解决方案仍然可以锁定我正在处理的行,并且在行锁定的情况下没有问题,因为我正在通过简单的重试进行抢救。 当记录解锁时,它会返回并重试工作

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