问题描述
我目前在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?
推荐答案
有了这个,我有了一个本机同步解决方案,它仍然可以锁定我正在处理的行,并且在行锁定的情况下没有问题,因为我通过简单的重试进行了救援.当记录被解锁后,它会返回并重试工作
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/并发.避免死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!