在silex中的事件调度程序

0 events dispatcher silex

我需要notifyService用Symphony的事件调度员替换我.

这是原始服务:

<?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);
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是我改变的内容:

<?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);
    }
}
Run Code Online (Sandbox Code Playgroud)

然而,正如我在文档中看到的那样,我需要一个监听器,但我无法弄清楚如何关联它,以及如何使它工作.

mTo*_*res 5

您需要重构代码.如文档中所述,为了分派事件,您必须创建事件并dispatchEventDispatcher实例上调用该方法,因此在您的代码中而不是您当前正在执行的操作:

<?php

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

你必须创建事件并直接发送它:

<?php

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

您现在也发送相同的事件('notify.action'),但之前您有2个不同的事件:'ready'和'unable_to_start',因此您必须为2个不同的事件创建2个侦听器('notify.success'和'例如,notify.unable_to_start'.

现在你还有两个问题:

  • 没有为'notify.action'事件配置侦听器,因此您必须在某处添加侦听器(您已经尝试但是您已经失败了,请参阅EventDispatcher组件的文档以获取有关如何正确配置侦听器的更多详细信息)
  • 您每次start创建方法时都要创建调度程序,因此每次都必须配置它(配置意味着添加侦听器)

如果通过基于Symfony EventDispatcher创建另一个服务来重构一下,你可以解决这两个问题:

<?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;
});
Run Code Online (Sandbox Code Playgroud)

请注意,$callable1$callable2在那里给你一个想法,再次检查文档以了解如何正确添加侦听器(您可以在处理事件的类中创建clousure或方法,这完全取决于您).

现在,您已经基于事件调度程序定义了一个notifyService(另一个与Silex使用的EventDispatcher完全不同,因此您的域事件有一个干净的事件调度程序),您可以将它用作您的类的通知服务.你可以像以前一样:使用setNotifyService方法,在代码中你只需要创建事件并调用dispatch方法(假设你已经调用了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);
Run Code Online (Sandbox Code Playgroud)

我希望这会让你走上正轨.

PS:您必须自己编写2个事件类,再次检查文档以获取详细信息.