本文介绍了Rails 4 Racing/并发.避免死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am currently using Sidekiq with the help of Sidekiq-Unique-Jobs and Sidekiq-Status to perform tasks on my application.

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

Jobs performed by workers are small and almost always executed immediately. (little or no queue at all)

我正在"hacking" sidekiq以同步执行任务(请检查控制器可以"找不到由工作人员创建的对象),这些作业体积小且执行速度快(通常少于1秒).而且我的应用程序需要同步运行作业并获取其详细信息(记录已创建/更新)

I am "hacking" sidekiq to perform tasks synchronously (check Controller can't find object created by worker), these jobs are small and fast to execute (less than 1 second usually). And my application needs to run the jobs synchronously and get its details (record created/updated)

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

With the "lame" solution I am using:

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

创建一个队列并通过参数(sidekiq-unique-jobs)确保同一用户同时执行不超过1个作业,我可以避免所有死锁,但是我认为这应该是执行此操作的更好方法,而不是入侵sidekiq,因为这是为了异步执行作业.

creating a queue and ensuring via params (sidekiq-unique-jobs) that no more than 1 job is simultaneously executed by the same user I can avoid all deadlocks, however I feel that it should be a better way to perform this, rather than hacking sidekiq since it's meant to perform jobs asynchronously.

问题是:sidekiq是否有其他替代或类似的gem可以限制输入,但默认情况下该同步意味着同步运行?我不能只问控制器Balance.find_or_create_by(user: user, market: market),因为它迟早会给我造成死锁(同时编辑/操作/创建记录),但是我觉得我使用的这种sidekiq解决方案也不行长期.我在这里缺少基本的东西吗?如何通过中间件或类似工具确保重复的参数/动作不会同时执行以避免死锁?

The question is: Is there any alternative or similar gem to sidekiq in the way that I can limit inputs BUT which is by default meant to be run synchronously? I can't just ask on controller Balance.find_or_create_by(user: user, market: market) because sooner or later it will give me deadlocks (records being edited /manipulated / created at the same time) but I feel that this sidekiq solution I'm using is also not ok on the long term. Am I missing something basic here?? How to ensure via middleware or something similar that duplicated params/action are not executed at the same time to avoid deadlocks?

推荐答案

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

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

With this I have a native synchronous solution that can still lock the rows I am working on, and in case of row locked there are no problem because I am rescuing with a simple retry. When records become unlocked it come back and retry the work

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

这篇关于Rails 4 Racing/并发.避免死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-16 06:09