You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Once we have run the job we'll go check if the memory limit has been exceeded
// for the script. If it has, we will kill this script so the process manager
// will restart this with a clean slate of memory automatically on exiting.
if ($this->memoryExceeded($memory)) {
$this->stop();
}
}
The run method on the process starts the process then calls wait on it. The wait method will continuously check the timeout to make sure that the process has not yet exceeded the timeout.
$timeoutMicro = microtime(true) + $timeout;
if ($this->isRunning()) {
// given SIGTERM may not be defined and that "proc_terminate" uses the constant value and not the constant itself, we use the same here$this->doSignal(15, false);
do {
usleep(1000);
} while ($this->isRunning() && microtime(true) < $timeoutMicro);
if ($this->isRunning()) {
// Avoid exception here: process is supposed to be running, but it might have stopped just// after this line. In any case, let's silently discard the error, we cannot do anything.$this->doSignal($signal ?: 9, false);
}
}
So, the listener process with kill the worker process when the worker process has run longer than the timeout. However, this does not work correctly in a Linux environment.
For example, let's say we run a listener like this: php artisan queue:listen database --timeout 10
On Mac, if you run ps -ef | grep queue, you will see something like the following:
As you can see, on Linux, the listener doesn't fork the worker command. Instead, it forks off the sh -c command that ends up forking the worker command. So, when the listener sends the SIGTERM signal to the worker, on a Mac the worker process dies, but on Linux the sh -c process dies instead of the worker.
See symfony/symfony#21474 and the related issues for more information on this issue, and for another way to create the process to avoid this issue.
Steps To Reproduce:
Run php artisan queue:listen database --timeout 5 --sleep 10. This will cause the listener to fork a process that will stay alive longer than the timeout.
Run ps -ef | grep "[q]ueue"
Wait for the timeout error on the listener
Run ps -ef | grep "[q]ueue" again.
On a Mac you will see that the worker is no longer running. On Linux you should still see the worker, but the sh -c command will have been killed.
The text was updated successfully, but these errors were encountered:
Uh oh!
There was an error while loading. Please reload this page.
Description:
The queue listener does not kill queue workers correctly on Linux.
Looking at the listener, it forks a worker process and calls
run
which will wait for the process to finish.framework/src/Illuminate/Queue/Listener.php
Lines 189 to 201 in ce0e5df
The run method on the process starts the process then calls
wait
on it. Thewait
method will continuously check the timeout to make sure that the process has not yet exceeded the timeout.https://github.com/symfony/process/blob/a867125524205460164c9ca95bc08199bb2da198/Process.php#L415
The check timeout method will stop the process if the timeout is exceeded.
https://github.com/symfony/process/blob/a867125524205460164c9ca95bc08199bb2da198/Process.php#L1188
The
stop
method with send a SIGTERM to the forked process to terminate it. It will then sleep for 1 millisecond, and if the process is still running it will send a SIGKILL to the process.https://github.com/symfony/process/blob/a867125524205460164c9ca95bc08199bb2da198/Process.php#L855
So, the listener process with kill the worker process when the worker process has run longer than the timeout. However, this does not work correctly in a Linux environment.
For example, let's say we run a listener like this:
php artisan queue:listen database --timeout 10
On Mac, if you run
ps -ef | grep queue
, you will see something like the following:On Linux, doing the same thing will give you the following
As you can see, on Linux, the listener doesn't fork the worker command. Instead, it forks off the
sh -c
command that ends up forking the worker command. So, when the listener sends the SIGTERM signal to the worker, on a Mac the worker process dies, but on Linux thesh -c
process dies instead of the worker.See symfony/symfony#21474 and the related issues for more information on this issue, and for another way to create the process to avoid this issue.
Steps To Reproduce:
php artisan queue:listen database --timeout 5 --sleep 10
. This will cause the listener to fork a process that will stay alive longer than the timeout.ps -ef | grep "[q]ueue"
ps -ef | grep "[q]ueue"
again.On a Mac you will see that the worker is no longer running. On Linux you should still see the worker, but the
sh -c
command will have been killed.The text was updated successfully, but these errors were encountered: