Worker exits when used with --stop-when-empty flag
Opened this issue · 1 comments
First of all, thank you for this nice package which is one of its kind when it comes to rate limiting without Redis.
I am not sure whether this is really an issue which can be solved by this package of not. But I want to log this information (even if you prefer to close it as out of scope) here as it will be helpful for other users of the package.
So, I am using worker in a mode where it exits when queue is empty. Like mentioned in laravel doc here https://laravel.com/docs/7.x/queues#running-the-queue-worker
php artisan queue:work --stop-when-empty
Now, let's say we have 10 items in the mail
queue and mail
queue is rate limited like this :
'rateLimits' => [
'mail' => [ // queue name
'allows' => 1, // 1 job
'every' => 5 // per 5 seconds
]
]
Now as soon as worker processes the first job & first job got complete within 2 seconds. Now, we have 9 jobs pending but just because of rate limit, none of job can be picked up within 5 seconds. This sends worker a signal that queue is empty and worker get terminated! Ideally, queue is yet not empty and work should resume the queue after 5 seconds.
Now for those who are using this package along with worker invoked from laravel scheduler like this (I know it should be from supervisor instead, but let's say due to some limitations):
$schedule->command('queue:work --stop-when-empty --timeout=120 --tries=3')->everyMinute();
They will get an impression like rateLimiter is limiting to 1 minute instead of seconds.. This is because worker process get terminated & it get invoked after 1 minutes (or with interval you have set in scheduler). So, that gives you impression like something is wrong with package configuration where every
parameter is in minutes instead of seconds :)
Possible work around for this is to set rate limits like this :
'rateLimits' => [
'default' => [ // queue name
'allows' => 12, // 12 job
'every' => 60 // per 1 minute
]
]
Above will make worker to pick 12 jobs per minutes. However, know that this can result in burst of 12 jobs per few seconds which might or might not work for you based on your scenario. (If API supports leaky bucket, it will work. If API has strict only second based limits, it might not work for you)
I can confirm this, with using laravel 8 and queue connection's driver as database '--stop-when-empty' tag is not working. It just logs 'Next job will be started in x seconds' and then nothing happens.