2016-05-27 3 views
0

Im пытается создать класс, расширяющий GearmanClient, поэтому я могу централизовать и использовать механизм в моем приложении в соответствии с моими собственными спецификациями. Одна из причин, по которой я делаю свой собственный класс, заключается в том, чтобы хранить легко сбойные задачи в базе данных, чтобы впоследствии их можно было обработать повторно.Ошибка расширения класса GearmanClient

Im получение основной погрешности

Предупреждение: GearmanClient :: runTasks(): _client_run_task (GEARMAN_NO_SERVERS) серверам не добавил -> libgearman/run.cc: 66 в/вар/WWW/HTML/приложение /forecast/Forecast.php на линии 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(); 
    } 
} 

Любой желающий может поделиться мне свет на это?

Спасибо!

+0

Вы смешиваете наследование и состав, которые могут быть причиной ошибки. Могли бы вы опубликовать Forecast.php или хотя бы строку 37? –

+0

Я обновил вопрос с помощью класса прогноза. Да, я могу это сделать. –

ответ

1

Как подозревали, причиной является то, что вы смешиваете inheritance and composition. Вы расширили класс GearmanClient, и в то же время вы создаете новый экземпляр класса GearmanClient в конструкторе и настраиваете этот новый экземпляр в методе , инициализируя.

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 :: клиент приватным и реализовать класс 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 в конструкторе и не меняйте , инициализируя методы.

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

В этом случае также не нужно менять линию 37, ни каких-либо других публичных методов класса вызовов GeamanClient.

+0

Отличный ответ! Очень ясно! Спасибо. –

Смежные вопросы