我在运行多个工作人员的设置中使用延迟工作。为了我的问题,它并不重要,但是假设我运行了10个工作人员(目前在开发模式下这样做)。
我遇到的问题是两个不同的工作人员有时会开始处理同一个工作,在我的工作对象上调用perform方法。
据我所知,延迟作业使用悲观锁定来防止这种情况发生,但似乎在第一个工人有时间实际锁定它之前,它有时仍有足够的时间来锁定工作。
我只是想问一下是否有其他人遇到过这个问题,或者我的设置是否行为不端。我正在使用Postrgres,这种情况发生在我的开发机器和Heroku上我主持它。
我会尝试在我的工作中解决这个问题,但这种情况仍然存在一些问题。理想情况下,延迟作业永远不会发生在两个进程的同一作业上。
谢谢!
答案 0 :(得分:0)
我们通过延迟工作与12名工人共同完成了约6,000万个工作岗位,并且从未报告此事。什么是你的延迟工作者正在运行的SQL?你使用的是改变postgres锁定行为的宝石吗?
以下是DJ sql对我的看法:
UPDATE "delayed_jobs" SET locked_at = '2014-05-02 21:16:35.419748', locked_by =
'host:whatever.local pid:4729' WHERE id IN (SELECT id FROM "delayed_jobs"
WHERE ((run_at <= '2014-05-02 21:16:35.415923'
AND (locked_at IS NULL OR locked_at < '2014-05-02 17:16:35.415947')
OR locked_by = 'host:whatever.local pid:4729') AND failed_at IS NULL)
ORDER BY priority ASC, run_at ASC LIMIT 1 FOR UPDATE) RETURNING *
您是否遇到任何其他代码的锁定问题?您可以尝试运行两个rails控制台会话并执行此操作:
控制台会话1:
User.find(1).with_lock do sleep(10); puts "worker 1 done" end
控制台会话2:
User.find(1).with_lock do sleep(1); puts "worker 2 done" end
同时启动这两个,如果2在1之前结束,那么你的锁定问题会更加普遍,因为推迟了工作。