Thanks to inspiration from https://gist.github.com/mauris/11375869, the scheduler job which runs every 5 minutes spawns a new queue:listen process and checks a local file with the process ID to see if it needs re-created or not.
Curious to hear your thoughts on this approach. It uses laravel's native withoutOverlapping logic that doing similar to what your solution is doing with the pid file. I think laravel just stores it in the storage dir.
@daem0n Just looking at that withoutOverlapping method - interesting.
It looks like Laravel might use the description of the task rather than the process id, so this might not handle if the process is killed for some reason outside of Laravel, i'm not sure.
Have you had any issues with using queue:work --daemon on your shared hosting?
Nope, its been solid so far. I used kill -9 on the process manually from another ssh session and sure enough it kickstarted it back up the next minute the cron job ran :)
The benefit is that the worker daemon keeps the same copy of the app code running, so its a bit more efficient. I also read in other threads that the queue:work --daemon is preferred over queue:listen.
@daem0n Just a quick update - I tried the queue:work --daemon setup but it looked like this was keeping the schedule:run command going and was creating several new queue:work commands.
I might not have set it up right, but I've gone back to the other setup for now.
I have the same problem.
The cronjob keeps the schedule:run live. The cron is running every minute and gives errors saying that "schedule:run" is already running (because schedule:run is never finished due to queue:work being still active)
I found this solution after 2 days research and GG help.
I write this function on app/Console/Kernel.php
protected function osProcessIsRunning($needle)
{
// get process status. the "-ww"-option is important to get the full output!
exec('ps aux -ww', $process_status);
// search $needle in process status
$result = array_filter($process_status, function($var) use ($needle) {
return strpos($var, $needle);
});
// if the result is not empty, the needle exists in running processes
if (!empty($result)) {
return true;
}
return false;
}
And this code to call it in method schedule()
// start the queue worker, if its not running
if (!$this->osProcessIsRunning('queue:work')) {
$schedule->command('queue:work')->everyMinute();
}