2016-05-27 6 views
0

GearmanClientというクラスを作成しようとしているので、自分の仕様に従って、アプリ全体でgearmanを集中管理できます。自分のクラスをやっている理由の1つは、簡単に失敗したタスクをデータベースに保存して、後で再び処理できるようにすることです。GearmanClientクラスを拡張する際のエラー

Imは基本的なエラーを取得し

警告:GearmanClient :: runTasks(): _client_run_task(GEARMAN_NO_SERVERS)は、サーバが追加されません - > libgearman/run.cc:66で/ var/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(); 
    } 

あなたは、コンストラクタで開始され、インスタンスを呼び出すようにしてGearmanClientクラスを拡張していないパブリックメソッドをGermanClientするライン37と他のすべての呼び出しを変更することができます。私的にプロパティGearman_service ::クライアントの可視性を変更し、GeamanClientクラスのパブリックインターフェイスを実装する方が良いだろうしかし

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

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クラスの新しいインスタンスを作成しないで、メソッドを初期化しないでください。

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

この場合も、37行もGeamanClientクラスのpublicメソッドも変更する必要はありません。

+0

Excelent応答!非常に明確な!ありがとうございました。 –

関連する問題