Rails 4 Racing / Concurrency。避免死锁

时间:2015-10-13 17:23:12

标签: ruby-on-rails ruby multithreading ruby-on-rails-3 ruby-on-rails-4

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

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

我是"黑客" sidekiq同步执行任务(检查Controller can't find object created by worker),这些作业很小并且执行起来很快(通常不到1秒)。我的应用程序需要同步运行作业并获取其详细信息(记录创建/更新)

" lame"我正在使用的解决方案:

<div class="wrapper">
  <input type="text" id="text">
  <input type="submit" id="submit">
</div>

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

问题是:对于sidekiq有没有替代或类似的宝石我可以限制输入BUT的方式,默认情况下是同步运行?我不能只在控制器 20.times do status = Sidekiq::Status::get balance, :exp_status if ["done"].include?(status) break end sleep(0.2) end 上询问,因为它迟早会给我死锁(同时编辑/操作/创建记录)但我觉得这个sidekiq解决方案我正在使用从长远来看也不行。我错过了一些基本的东西吗?如何确保通过中间件或类似的东西同时执行重复的参数/动作以避免死锁?

2 个答案:

答案 0 :(得分:2)

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

FOSS

Sidekiq Enterprise's official API

答案 1 :(得分:2)

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

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

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