Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing to see if Gearman daemon is running

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)
like image 218
HyderA Avatar asked Dec 08 '22 19:12

HyderA


1 Answers

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

like image 162
Layke Avatar answered Dec 12 '22 12:12

Layke