Closed trevorgehman closed 4 years ago
Laravel Version: 5.6.x & above
Did you test this on Laravel 6?
I've actually only just noticed it in 5.8.35. I imagine this works the same in 6.x since this code is the same:
The worker calls getNextJob
for each queue in order:
Which calls pop
and retrieveNextJob
on the Redis queue:
You can see that BLPOP
is called for each queue (line 233):
So it's going to block for (in this case) 5 seconds before checking the next queue in the priority list.
@trevorgehman feel free to open up a new issue once you were able to confirm this on 6.x
@trevorgehman feel free to open up a new issue once you were able to confirm this on 6.x
It can be confirmed that this problem exists in 6.x and 7.x
The same is in 9.x, 10.x, and 11.x as well. Just spent a day on the jobs performance bottlenecks and reverse engineering both empty laravel and our own project to finally find this issue out. ;)
Description:
If you use
block_for
and also utilize queue priorities, the worker will block on each queue sequentially. This could result in much longer queue processing times.Steps To Reproduce:
For example, suppose you set
block_for=5
and spawn a worker like this:The worker will block on the
high
queue for 5 seconds, then themedium
queue, then thelow
queue, and finally thedefault
queue. This means that it could take up to 15 seconds before a job in thedefault
queue is picked up, even if it is the only job in any of the queues.More seriously, if you set
block_for=0
the worker will indefinitely block on thehigh
queue, and the other queues will never be reached.Solution:
I'm not sure if this is a bug, but I initially assumed that the worker would block on all the queues set for the worker and immediately pick up a new job in any of them.
Perhaps all that's needed is an addition to the documentation recommending that the
block_for
setting only be used when workers listen to a single queue...