2016-05-27 14 views
0

Ich versuche, eine Klasse zu erstellen, die GearmanClient erweitert, damit ich gearman über meine App nach meinen eigenen Spezifikationen zentralisieren und verwenden kann. Einer der Gründe, warum ich meine eigene Klasse mache, besteht darin, einfach fehlgeschlagene Aufgaben in einer Datenbank zu speichern, damit sie später erneut verarbeitet werden können. GearmanClient :: runTasks():Fehler beim Erweitern der GearmanClient-Klasse

Im einen grundlegenden Fehler

Warnung bekommen _client_run_task (GEARMAN_NO_SERVERS) keine Server hinzugefügt -> libgearman/run.cc: 66 in/var/www/html/app /forecast/Forecast.php auf Linie 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; 
    } 

} ich muss mit dieser Implementierung stimmt etwas nicht übernehmen, aber ich würde warum wissen.

Die Config_helper::get_config_option('gearman_servers'); ruft meine Liste der Server korrekt ab.

Das ist meine Prognose Klasse

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

Wer kann mir ein Licht auf diese teilen?

Vielen Dank!

+0

Sie mischen Vererbung und Zusammensetzung, die Ursache des Fehlers sein könnte. Könnten Sie Forecast.php oder mindestens Zeile 37 posten? –

+0

Ich habe die Frage mit der Vorhersageklasse aktualisiert. Ja, ich mache das vielleicht. –

Antwort

1

Wie vermutet ist die Ursache des Problems, dass Sie inheritance and composition mischen. Sie haben die GearmanClient-Klasse erweitert und erstellen gleichzeitig eine neue Instanz der GearmanClient-Klasse im Konstruktor und konfigurieren diese neue Instanz in der Methode initialisieren.

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

Sie können die Linie 37 ändern und alle anderen Anrufe öffentliche Methoden GermanClient die Instanz in Konstruktor initiiert rufen und nicht GearmanClient Klasse erweitern.

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

Allerdings wäre es besser, die Sichtbarkeit der Immobilie Gearman_service :: Client privat zu ändern und GeamanClient Klasse öffentliche Schnittstelle zu implementieren.

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

Wenn Sie dies tun, sollte die Linie 37 so bleiben wie sie ist.

Alternativ könnten Sie für die Vererbung entscheiden. In diesem Fall müssten Sie den öffentlichen Eigenschaft-Client entfernen, keine neue Instanz der GeamanClient-Klasse im Konstruktor erstellen und die Methoden initialisieren Methoden ändern. noch andere Anrufe GeamanClient Klasse öffentliche Methoden

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

In diesem Fall werden Sie brauchen, um die Leitung 37 nicht zu verändern.

+0

Ausgezeichnete Antwort! Sehr deutlich! Vielen Dank. –