2013-03-25 72 views
7

我在运行多个工作人员的设置中使用延迟作业。为了我的问题,这并不重要,但假设我运行了10名员工(目前正在开发模式中)。启动同一作业的多个延迟作业进程

我遇到的问题是两个不同的工作人员有时会开始在同一个工作上工作,在我的工作对象上调用执行方法。

据我所知,延迟作业使用悲观锁定来防止这种情况发生,但它似乎有时还有足够的时间锁定在第一个工作者有时间实际锁定之前盗取作业。

我只是要求看看是否有其他人遇到过这个问题,或者如果它是我的设置是行为不当。我正在使用Postrgres,这发生在我的开发机器和Heroku中,我托管它。

我会尽力在我的工作中解决它,但是这样做仍然有点问题。理想情况下,延迟工作不会发生在两个流程的同一工作上。

谢谢!

+0

我看到类似的东西。无法完全追踪它,但似乎在检查锁定和锁定之间,多名工作人员正在抓取并执行工作。 – 2013-03-25 18:23:08

+0

我应该说我发现在初始化器中设置'''Delayed :: Worker.read_ahead = 1''似乎可以缓解这个问题。 – 2013-03-25 18:52:37

+0

有Resque相同的问题,没有找到解决方案 – 2013-03-25 18:57:33

回答

0

我们已经通过延迟的工作与12名工人运行了大约6000万个工作,从未有过这方面的报告。什么是你的延迟工作的工作人员正在运行的SQL?您是否正在使用改变postgres锁定行为的gem?

这里是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 * 

你已经锁定问题与任何其他代码?你能尝试运行两个轨道控制台会话和这样做:

控制台会话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,你的锁定问题更普遍,推迟了工作。