2015-04-27 59 views
0

我需要用Symphony的事件調度程序替換我的notifyService在silex中的事件調度程序

這裏是原來的服務:

<?php 

class VmService 
{ 
    /** 
    * @var VmManager|null 
    */ 
    protected $vmManager = null; 

    /** 
    * @var ProvisionerInterface[] 
    */ 
    protected $provisionners = array(); 

    /** 
    * @var NotifyService|null 
    */ 
    protected $notifyService = null; 

    public function setVmManager(VmManager $vmManager) 
    { 
     $this->vmManager = $vmManager; 
    } 

    public function getVmManager() 
    { 
     return $this->vmManager; 
    } 

    /** 
    * @param $type 
    * @param ProvisionerInterface $provisionner 
    */ 
    public function setProvisionner($type, ProvisionerInterface $provisionner) 
    { 
     $this->provisionners[$type] = $provisionner; 
    } 

    /** 
    * @param $type 
    * @return ProvisionerInterface 
    */ 
    public function getProvisionner(Vm $vm) 
    { 
     return $this->provisionners[$vm->getType()]; 
    } 

    /** 
    * @param NotifyService $notifyService 
    */ 
    public function setNotifyService(NotifyService $notifyService) 
    { 
     $this->notifyService = $notifyService; 
    } 

    /** 
    * @return NotifyService|null 
    */ 
    public function getNotifyService() 
    { 
     return $this->notifyService; 
    } 

    public function initialise(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 
     $provisioner = $this->getProvisionner($vm); 
     $provisioner->initialise($vm); 
     $vm->setStatus(VM::STOPPED); 
     $vmManager->flush($vm); 
    } 

    public function delete(Vm $vm, $force = false) 
    { 
     $now = new \DateTime(); 
     $day = $now->format('w'); 
     if (($day == 0 || $day == 6) && ! $force) { 
      throw new \Exception('Cannot delete a VM on weekend unless you force it'); 
     } 

     $vmManager = $this->getVmManager(); 
     $provisioner = $this->getProvisionner($vm); 
     $provisioner->delete($vm); 

     $vm->setStatus(Vm::STOPPED); 
     $vmManager->flush($vm); 
    } 

    private function deleteLogFile(Vm $vm) 
    { 
     $filename = VmLogger::getLogFile($vm->getIdVm()); 
     if (file_exists($filename)) { 
      @unlink("$filename"); 
     } 
    } 

    public function prepare(Vm $vm) 
    { 
     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 

     //$provisionner->start($vm, true, 'integ.lafourchette.local'); 
     $provisionner->stop($vm); 
    } 

    public function start(Vm $vm, $provisionEnable = true) 
    { 
     $vmManager = $this->getVmManager(); 
     $notify = $this->getNotifyService(); 

     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 

     $vm->setStatus(VM::STARTED); 
     $vmManager->flush($vm); 
     try { 
      $provisionner->start($vm, $provisionEnable); 

      $vm->setStatus(VM::RUNNING); 
      $vmManager->flush($vm); 
      $notify->send('ready', $vm); 

     } catch (UnableToStartException $e) { 
      $vm->setStatus(VM::STOPPED); 
      $vmManager->flush($vm); 
      $notify->send('unable_to_start', $vm); 
      throw $e; 
     } 
    } 

    public function getStatus(Vm $vm) 
    { 
     return $this->getProvisionner($vm)->getStatus($vm); 
    } 

    public function stop(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 

     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 
     $vm->setStatus(Vm::STOPPED); 
     $vmManager->flush($vm); 
     $provisionner->stop($vm); 
    } 

    public function archived(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 
     $this->delete($vm); 
     $vm->setStatus(VM::EXPIRED); 
     $this->deleteLogFile($vm); 
     $vmManager->flush($vm); 
     $this->prepare($vm); 
    } 
} 

這裏是我已經改變了:

<?php 

class VmService 
{ 
    /** 
    * @var VmManager|null 
    */ 
    protected $vmManager = null; 

    /** 
    * @var ProvisionerInterface[] 
    */ 
    protected $provisionners = array(); 

    /** 
    * @var NotifyService|null 
    */ 
    protected $notifyService = null; 

    public function setVmManager(VmManager $vmManager) 
    { 
     $this->vmManager = $vmManager; 
    } 

    public function getVmManager() 
    { 
     return $this->vmManager; 
    } 

    /** 
    * @param $type 
    * @param ProvisionerInterface $provisionner 
    */ 
    public function setProvisionner($type, ProvisionerInterface $provisionner) 
    { 
     $this->provisionners[$type] = $provisionner; 
    } 

    /** 
    * @param $type 
    * @return ProvisionerInterface 
    */ 
    public function getProvisionner(Vm $vm) 
    { 
     return $this->provisionners[$vm->getType()]; 
    } 

    /** 
    * @param NotifyService $notifyService 
    */ 
    public function setNotifyService(NotifyService $notifyService) 
    { 
     $this->notifyService = $notifyService; 
    } 

    /** 
    * @return NotifyService|null 
    */ 
    public function getNotifyService() 
    { 
     return $this->notifyService; 
    } 

    public function initialise(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 
     $provisioner = $this->getProvisionner($vm); 
     $provisioner->initialise($vm); 
     $vm->setStatus(VM::STOPPED); 
     $vmManager->flush($vm); 
    } 

    public function delete(Vm $vm, $force = false) 
    { 
     $now = new \DateTime(); 
     $day = $now->format('w'); 
     if (($day == 0 || $day == 6) && ! $force) { 
      throw new \Exception('Cannot delete a VM on weekend unless you force it'); 
     } 

     $vmManager = $this->getVmManager(); 
     $provisioner = $this->getProvisionner($vm); 
     $provisioner->delete($vm); 

     $vm->setStatus(Vm::STOPPED); 
     $vmManager->flush($vm); 
    } 

    private function deleteLogFile(Vm $vm) 
    { 
     $filename = VmLogger::getLogFile($vm->getIdVm()); 
     if (file_exists($filename)) { 
      @unlink("$filename"); 
     } 
    } 

    public function prepare(Vm $vm) 
    { 
     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 

     //$provisionner->start($vm, true, 'integ.lafourchette.local'); 
     $provisionner->stop($vm); 
    } 

    public function start(Vm $vm, $provisionEnable = true) 
    { 
     $vmManager = $this->getVmManager(); 
     $dispatcher = new EventDispatcher(); 

     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 
     $vm->setStatus(VM::STARTED); 
     $vmManager->flush($vm); 
     try { 
      $provisionner->start($vm, $provisionEnable); 

      $vm->setStatus(VM::RUNNING); 
      $vmManager->flush($vm); 
      $event = new NotifyEvent($vm); 
      $dispatcher->addListener('notify.action', $event); 
      $dispatcher->dispatch('notify.action'); 


     } catch (UnableToStartException $e) { 
      $vm->setStatus(VM::STOPPED); 
      $vmManager->flush($vm); 
      $event = new NotifyEvent($vm); 
      $dispatcher->addListener('notify.action', $event); 
      $dispatcher->dispatch('notify.action'); 

      throw $e; 
     } 
    } 

    public function getStatus(Vm $vm) 
    { 
     return $this->getProvisionner($vm)->getStatus($vm); 
    } 

    public function stop(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 

     /** 
     * @var VM $vm 
     */ 
     $provisionner = $this->getProvisionner($vm); 
     $vm->setStatus(Vm::STOPPED); 
     $vmManager->flush($vm); 
     $provisionner->stop($vm); 
    } 

    public function archived(Vm $vm) 
    { 
     $vmManager = $this->getVmManager(); 
     $this->delete($vm); 
     $vm->setStatus(VM::EXPIRED); 
     $this->deleteLogFile($vm); 
     $vmManager->flush($vm); 
     $this->prepare($vm); 
    } 
} 

然而,由於我的文檔看,我需要一個傾聽者,但我不能弄清楚如何聯繫它,以及如何使其發揮作用。

回答

5

你需要重構你的代碼。 As stated in the documentation,以分發事件,你必須創建活動,並呼籲此事件實例dispatch方法,所以在你的代碼,而不是你在做什麼目前:

<?php 

// this is the start method of your service 
// ... 
$event = new NotifyEvent($vm); 
$dispatcher->addListener('notify.action', $event); 
$dispatcher->dispatch('notify.action'); 
// ... 

你必須創建現在

<?php 

// this is the start method of your service 
// ... 
$event = new NotifyEvent($vm); 
$dispatcher->dispatch('notify.action', $event); 
// ... 

您也發送相同的事件(「notify.action」),但以前你有2個不同的事件:該事件並直接派遣其「準備」和「unable_to_start」,所以你必須創建2個不同事件的監聽器('notify.success'和'notify。例如'unable_to_start')。

現在你有2個問題:

  • 沒有監聽器的配置適合您「notify.action」事件,所以你必須從某個地方添加監聽器(你試過,但你已經失敗了,有關如何正確配置偵聽器的更多詳細信息,請參閱EventDispatcher組件的文檔)
  • 您每創建一次start方法都會創建調度程序,因此您必須每次都配置它(配置意味着添加偵聽器)

可以解決這兩個如果您通過創建基於該Symfony的此事件的另一個服務重構一點點:

<?php 
// somewhere in your config file 
// ... 

$app['notifyService'] = $app->share(function() use ($app) { 
    $dispatcher = new Symfony\Component\EventDispatcher\EventDispatcher(); 
    $dispatcher->addListener('notify.success', $callable1); 
    $dispatcher->addListener('notify.unable_to_start', $callable2); 

    return $dispatcher; 
}); 

注意$callable1$callable2在那裏給你一個想法,再次檢查documentation怎麼看要正確添加監聽器(可以在處理事件的類中創建clousure或方法,這完全取決於您)。

現在您已經基於Event Dispatcher定義了一個notifyService(另一個與Silex使用的完全不同的EventDispatcher,因此您有一個乾淨的Event Dispatcher用於您的域事件),您可以將它用作您的通知服務類。你會做它像以前一樣:使用setNotifyService方法並在代碼中,你只需要創建事件,並調用調度方法(假設你已經叫setNotifyService):

<?php 
// class VmService 
// method start 
// when you've to dispatch the success event 
$event = new NotifySuccessEvent($vm); 
$this->notifyService->dispatch('notify.success', $event); 

// if you have to dispatch the notify.unable_to_start event 
$event = new NotifyUnableToStartEvent($vm); 
$this->notifyService->dispatch('notify.unable_to_start', $event); 

我希望這會讓你走上正軌。 PS:你必須自己編寫2個事件類,再次檢查文檔的細節。

+0

謝謝你,你真的幫我一把! – Chrysem