Ошибка при расширении класса GearmanClient
Я пытаюсь создать класс, расширяющий GearmanClient, чтобы я мог централизовать и использовать gearman в своем приложении в соответствии со своими спецификациями. Одна из причин, по которой я занимаюсь своим собственным классом, заключается в том, чтобы легко сохранять невыполненные задачи в базе данных, чтобы впоследствии их можно было снова обработать.
Я получаю основную ошибку
Предупреждение: GearmanClient::runTasks(): _client_run_task(GEARMAN_NO_SERVERS) без добавления серверов -> libgearman/run.cc:66 в /var/www/html/app/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();
}
}
Кто-нибудь может поделиться со мной светом на это?
Спасибо!
1 ответ
Как и предполагалось, причиной проблемы является то, что вы смешиваете наследование и композицию. Вы расширили класс 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 в конструкторе и не изменяйте методы инициализации.
protected function initialize()
{
foreach($this->servers as $key => $value):
$this->addServer($value[0],$value[1]);
endforeach;
}
В этом случае вам также не нужно менять строку 37 или другие вызовы открытых методов класса GeamanClient.