When PHP Gearman client fails to connect to the server I get the same code as when it fail to get new jobs

StackOverflow https://stackoverflow.com/questions/16815420

  •  30-05-2022
  •  | 
  •  

문제

PHP Gearman worker retrieves tasks from the server. When we don't have any new tasks we do some other work in the background. Please check the implementation below.

$worker = new GearmanWorker();
$worker->addServer('host', 123);
$worker->addFunction('name', array($this, 'function'));
$worker->setTimeout(5000);

while ($worker->work() || GEARMAN_TIMEOUT == $worker->returnCode()) {
    if (GEARMAN_TIMEOUT == $worker->returnCode()) {
        $this->handleTimeout();
    } elseif (GEARMAN_SUCCESS != $worker->returnCode()) {
        $this->handleFail();
        break;
    }
}

The code looks very simple and works normally most of the times. But when for some reason the script fails to connect to the server the $worker->returnCode() is equal to GEARMAN_TIMEOUT.

The $worker->returnCode() value is the same

  • when we don't have any new tasks
  • when script fails to connect to the server

When script fails to connect to the server the error message and code are the following:

  • $worker->error()

    gearman_worker_grab_job(GEARMAN_TIMEOUT) Option timeout return reached -> libgearman/worker.cc:869

  • $worker->getErrno()

    0

How to catch error when client fails to connect to server?

도움이 되었습니까?

해결책

We have added GearmanWorker::echo() call to check if the Gearman server is available.

Look at the code after changes

$worker = new GearmanWorker();
$worker->addServer('host', 123);
$worker->addFunction('name', array($this, 'function'));
$worker->setTimeout(5000);

while ($worker->work() || GEARMAN_TIMEOUT == $worker->returnCode()) {
    if (GEARMAN_TIMEOUT == $worker->returnCode()) {
        $this->handleTimeout();
        $echo = @$worker->echo(1);
        if (!$echo) {
            echo 'Failed to connect to Gearman Gerver.'. PHP_EOL;
            break;
        }
    } elseif (GEARMAN_SUCCESS != $worker->returnCode()) {
        $this->handleFail();
        break;
    }
}

Please note the line $echo = @$worker->echo(1); and checks bellow. If server is unavailable then echo() output PHP warning and returns false.

GearmanException is never thrown in our setup.

다른 팁

For basic solution you can use code like this:

try {
while ($worker->work() || GEARMAN_TIMEOUT == $worker->returnCode()) {
    if (GEARMAN_TIMEOUT == $worker->returnCode()) {
        echo "Timeout...\n";
    } elseif (GEARMAN_SUCCESS != $worker->returnCode()) {
        echo "Fail...\n";
        break;
    }
}
} catch (GearmanException $e) {
  echo "Exception caused!\n";
}

But you can not leave worker alive, because it needs to connect. I suggest to use Supervisord for automatically restart workers.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top