Rails 4 Racing/Concurrency。避免死锁
Rails 4 Racing/Concurrency. Avoid Deadlock
我目前在 Sidekiq-Unique-Jobs 和 Sidekiq-Status 的帮助下使用 Sidekiq 在我的应用程序上执行任务。
工人完成的工作很少,而且几乎总是立即执行。 (很少或根本没有排队)
我是 "hacking" sidekiq 同步执行任务(检查 Controller can't find object created by worker),这些作业很小而且执行速度很快(通常不到 1 秒)。我的应用程序需要同步 运行 作业并获取其详细信息(记录 created/updated)
我使用的 "lame" 解决方案:
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,因为它旨在异步执行作业。
问题是:在我可以限制输入的方式上,是否有替代或类似 gem 的 sidekiq,但默认情况下是 运行同步?我不能只在控制器 Balance.find_or_create_by(user: user, market: market)
上询问,因为它迟早会给我带来死锁(同时编辑/操作/创建记录),但我觉得我正在使用的这个 sidekiq 解决方案也不行从长远来看。我在这里错过了一些基本的东西吗?如何通过中间件或类似的东西确保重复的 params/action 不会同时执行以避免死锁?
你正在拼凑一个穷人的分布式互斥体。还有更好的方法。
我用 Redis-Mutex 解决了我的问题。
有了这个,我有了一个本机同步解决方案,它仍然可以锁定我正在处理的行,如果行被锁定,也没有问题,因为我正在通过简单的重试来拯救。当记录解锁时,它会返回并重试工作
def enter
RedisMutex.with_lock(user) do
# hard-work
end
rescue RedisMutex::LockError
retry
end
我目前在 Sidekiq-Unique-Jobs 和 Sidekiq-Status 的帮助下使用 Sidekiq 在我的应用程序上执行任务。
工人完成的工作很少,而且几乎总是立即执行。 (很少或根本没有排队)
我是 "hacking" sidekiq 同步执行任务(检查 Controller can't find object created by worker),这些作业很小而且执行速度很快(通常不到 1 秒)。我的应用程序需要同步 运行 作业并获取其详细信息(记录 created/updated)
我使用的 "lame" 解决方案:
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,因为它旨在异步执行作业。
问题是:在我可以限制输入的方式上,是否有替代或类似 gem 的 sidekiq,但默认情况下是 运行同步?我不能只在控制器 Balance.find_or_create_by(user: user, market: market)
上询问,因为它迟早会给我带来死锁(同时编辑/操作/创建记录),但我觉得我正在使用的这个 sidekiq 解决方案也不行从长远来看。我在这里错过了一些基本的东西吗?如何通过中间件或类似的东西确保重复的 params/action 不会同时执行以避免死锁?
你正在拼凑一个穷人的分布式互斥体。还有更好的方法。
我用 Redis-Mutex 解决了我的问题。
有了这个,我有了一个本机同步解决方案,它仍然可以锁定我正在处理的行,如果行被锁定,也没有问题,因为我正在通过简单的重试来拯救。当记录解锁时,它会返回并重试工作
def enter
RedisMutex.with_lock(user) do
# hard-work
end
rescue RedisMutex::LockError
retry
end