扩展 GearmanClient 时出错 class

Error extending GearmanClient class

我正在尝试创建一个 class 扩展 GearmanClient,以便我可以根据自己的规范在我的应用程序中集中和使用 gearman。我自己做 class 的原因之一是将容易失败的任务存储到数据库中,以便以后可以再次处理它们。

我遇到了一个基本错误

Warning: GearmanClient::runTasks(): _client_run_task(GEARMAN_NO_SERVERS) no servers added -> libgearman/run.cc:66 in /var/www/html/app/forecast/Forecast.php on line 37

<?php
namespace app\service;
use helpers\Config_helper;
use \GearmanClient;

class Gearman_service extends GearmanClient
{
    public $client;
    private $servers = array();
    private $tasks   = array();

    private $completedTasks = array();
    private $failedTasks    = array();

    private $maxRetryAttempts;

    public function __construct()
    {       
        $this->client = new GearmanClient();            
        $this->servers = Config_helper::get_config_option('gearman_servers');
        $this->maxRetryAttempts = Config_helper::get_config_option('gearman_retry_attempts');

        $this->initialize();
    }

    protected function initialize()
    {
        foreach($this->servers as $key => $value):
            $this->client->addServer($value[0],$value[1]);
        endforeach;
    }

} 我必须假设这个实现有问题,但我想知道为什么。

Config_helper::get_config_option('gearman_servers'); 正在正确检索我的服务器列表。

这是我的预测class

<?php
namespace app\forecast;
use app\service\Gearman_service;
use helpers\Config_helper;
use helpers\Urlrequest_helper;
use app\warehouse\models\Client_time_forecast;

abstract class Forecast
{
    public $coordinates = array(); # set of coordinates
    public $servers     = array();
    public $variables   = array();
    public $url         = array();
    public $prevision;
    public $client;

    public $gearmanclient;

    public function __construct()
    {
        $this->servers   = Config_helper::get_config_option('forecast_servers');
        $this->variables = Config_helper::get_config_option('surface_variables');
        $this->prevision = Config_helper::get_config_option('forecast_prevision');

        $this->gearmanclient = new Gearman_service();       
    }

    public function storeResults()
    {               
        $this->gearmanclient->setCompleteCallback(array($this, 'requestComplete'));

        foreach($this->url as $key => $value):          
            $this->gearmanclient->addTask('request_forecast', serialize($value[0]));
        endforeach;

        $this->gearmanclient->runTasks();       // **line 37**  
    }   

    /**
     * [requestComplete store request results in cassandra db]
     * @param  \GearmanTask $task [description]
     * @return [boolean]          
     */
    public function requestComplete(\GearmanTask $task)
    {
        $persistent = new Client_time_forecast($this->client, unserialize($task->data()));
        $persistent->storeData();
    }
}

任何人都可以与我分享这方面的知识吗?

谢谢!

怀疑问题的原因是你在混合inheritance and composition。您扩展了 GearmanClient class,同时您在构造函数中创建了 GearmanClient class 的新实例,并在方法 initialize 中配置了这个新实例。

class Gearman_service extends GearmanClient
{
    public $client;
    // other properties
    public function __construct()
    {       
        $this->client = new GearmanClient();
        // more code
        $this->initialize();
    }

您可以更改第 37 行和所有其他对 GermanClient public 方法的调用,以调用在构造函数中启动的实例并且不扩展 GearmanClient class.

$this->gearmanclient->client->runTasks(); 

然而,最好将 属性 Gearman_service::client 的可见性更改为私有并实现 GeamanClient class public 接口。

class Gearman_service extends GearmanClient
{

    private $client;

    // constructor etc

    public function addTask($name, $workload, $context = null, $unique = "")
    {
        return $this->client->addTask($name, $workload, $context, $unique);
    }

如果你这样做,第 37 行应该保持原样。

或者您可以选择继承。在这种情况下,您需要删除 public 属性 客户端,不要在构造函数中创建 GeamanClient class 的新实例并更改 initialize方法。

protected function initialize()
{
    foreach($this->servers as $key => $value):
        $this->addServer($value[0],$value[1]);
    endforeach;
}

在这种情况下,您也不需要更改第 37 行或任何其他调用 GeamanClient class public 方法。