扩展GearmanClient类时出错

时间:2016-05-27 19:04:42

标签: php gearman

我正在尝试创建一个扩展 GearmanClient 的类,这样我就可以根据自己的规范在我的应用程序中集中并使用gearman。我自己上课的原因之一是将失败的任务存储到数据库中,以便以后再处理。

我得到一个基本错误

  

警告:GearmanClient :: runTasks():   _client_run_task(GEARMAN_NO_SERVERS)未添加任何服务器 - > libgearman / run.cc:66/var/www/html/app/forecast/Forecast.php on   第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');正在正确检索我的服务器列表。

这是我的预测课程

<?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();
    }
}

任何人都可以分享一下这个问题吗?

谢谢!

1 个答案:

答案 0 :(得分:1)

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

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

您可以更改第37行以及对GermanClient公共方法的所有其他调用,以调用在构造函数中启动的实例,并且不会扩展GearmanClient类。

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

然而,最好将属性Gearman_service :: client的可见性更改为private并实现GeamanClient类公共接口。

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行应保持不变。

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

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

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