Delayed::Job.work_off not processing items in the queue in the order in which they were added #15

klingerf opened this Issue Nov 17, 2009 · 4 comments

2 participants


Perhaps the Delayed::Job queue is order agnostic, but I would expect it to process jobs of the same priority in the same order as they were added to the queue.

Here's a failing test that I wrote against one of my models:

def test_delayed_job
comment = Comment.create!(:body => 'This is a comment')
assert_equal 0, Delayed::Job.find(:all).size
comment.send_later(:update_attribute, :body, 'Comment the first')
comment.send_later(:update_attribute, :body, 'Comment the second')
assert_equal [2, 0], Delayed::Job.work_off
assert_equal 'Comment the second', comment.reload.body

Unfortunately, that test fails with the following output:

<"Comment the second"> expected but was <"Comment the first">.

The order in which the two updates are dequeued differs from the order in which the two updates were enqueued. Is this the expected behavior?


Looking at the code, it is correct that it tries to do this in random order. Over the code to randomize the ordering is probably ill-advised (as a strategy), but even if it is the implementation is buggy.

records.sort { rand() }

This does not do a random sort like you'd expect. Worst case it'll do nothing or even worst worst case it'll be an infinite loop.

I'm going to create a new issue on this.


Oops, nope on second thought this does work in terms of being random. I forgot how sort first does a map/collect first.

But does this strategy make sense?


I would disagree that the correct behavior is to dequeue items of the same priority in random order; calling it a queue implies that order should be maintained.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment