I want to check to see if Gearman daemon is running. And only then run tasks so my application does not crash.
Here's my code:
$daemonRunning = true;
while( true )
{
try
{
Yii::app()->gearman->client->ping( true );
if ( $daemonRunning === false )
{
echo "Daemon back online. Starting signature process...\n";
}
Yii::app()->gearman->client->runTasks();
}
catch( GearmanException $e )
{
echo "Daemon appears to be down. Waiting for it to come back up...\n";
$daemonRunning = false;
}
sleep(1);
}
But the issue is that ping
does not throw an exception, it throws a fatal error:
PHP Error[2]: GearmanClient::ping(): flush(GEARMAN_COULD_NOT_CONNECT) 127.0.0.1:4730 -> libgearman/connection.cc:673
Though oddly, if I remove ping
, and use only runTasks
, then an exception is thrown.
Related:
How do I handle the error when Gearman daemon goes down while processes are running? I get the following error from PHP when I bring down the Gearman daemon:
php: libgearman/universal.cc:481: gearman_return_t connection_loop(gearman_universal_st&, const gearman_packet_st&, Check&): Assertion `&con->_packet == universal.packet_list' failed.
Aborted (core dumped)
At it's most basic, checking the status of a Gearman server can be done through command line using:
(echo status ; sleep 0.1) | nc 127.0.0.1 4730 -w 1
However as noted in this question, you can use fsocketopen
to get he status of the gearman server.
// Taken from https://stackoverflow.com/questions/2752431/any-way-to-access-gearman-administration
class Waps_Gearman_Server {
/**
* @var string
*/
protected $host = "127.0.0.1";
/**
* @var int
*/
protected $port = 4730;
/**
* @param string $host
* @param int $port
*/
public function __construct($host=null,$port=null){
if( !is_null($host) ){
$this->host = $host;
}
if( !is_null($port) ){
$this->port = $port;
}
}
/**
* @return array | null
*/
public function getStatus(){
$status = null;
$handle = fsockopen($this->host,$this->port,$errorNumber,$errorString,30);
if($handle!=null){
fwrite($handle,"status\n");
while (!feof($handle)) {
$line = fgets($handle, 4096);
if( $line==".\n"){
break;
}
if( preg_match("~^(.*)[ \t](\d+)[ \t](\d+)[ \t](\d+)~",$line,$matches) ){
$function = $matches[1];
$status['operations'][$function] = array(
'function' => $function,
'total' => $matches[2],
'running' => $matches[3],
'connectedWorkers' => $matches[4],
);
}
}
fwrite($handle,"workers\n");
while (!feof($handle)) {
$line = fgets($handle, 4096);
if( $line==".\n"){
break;
}
// FD IP-ADDRESS CLIENT-ID : FUNCTION
if( preg_match("~^(\d+)[ \t](.*?)[ \t](.*?) : ?(.*)~",$line,$matches) ){
$fd = $matches[1];
$status['connections'][$fd] = array(
'fd' => $fd,
'ip' => $matches[2],
'id' => $matches[3],
'function' => $matches[4],
);
}
}
fclose($handle);
}
return $status;
}
}
In regards to your second question, I have never been able to recover a gearman worker when the connect is lost midwork. You basically have to kill the entire process running the client worker, and let supervisor take back over and restart another worker process. Gearman client workers should be extremeley ephemeral. You should be monitoring them for memory usage regularly and auto killing them. So, if you ever hit a segfault/coredump, killing the worker is totally normal.
As mentioned, you can auto start back up your workers using Supervisor. Also check this out, it explains how to get Gearman Clients working with Supervisor
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With