我正在尝试创建一个扩展 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();
}
}
任何人都可以分享一下这个问题吗?
谢谢!
答案 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类的公共方法。