Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the Symfony 2 Event Dispatcher

How, if at all, should a Symfony 2 bundle developer use the event dispatcher(s) that ship with a stock Symfony 2 system?

I've been digging around in the source for Symfony's event dispatcher, and some of what I've seen has me a little confused as to how I, a third party bundle creator, should use the event dispatcher that ships with Symfony.

Specifically, I noticed that a stock Symfony system has two event dispatcher services. The event_dispatcher and the debug.event_dispatcher. Which service the HttpKernel uses is dependent on environment, and driven by the generated dev or prod container file.

//dev kernel instantiation uses `debug.event_dispatcher` service
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
            $this->get('debug.event_dispatcher'), 
            $this, 
            $this->get('debug.controller_resolver')
        );

//prod kernel instantiation uses `event_dispatcher` service         
new \Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel(
            $this->get('event_dispatcher'), 
            $this, 
            new \Symfony\Bundle\FrameworkBundle\Controller\ControllerResolver($this, $this->get('controller_name_converter'), $this->get('monolog.logger.request', ContainerInterface::NULL_ON_INVALID_REFERENCE)));

So far this all makes sense — as it's the debug.event_dispatcher that implements functionality in the web profile's event's tab, including the ability to see which listeners were called, and which listeners were not called.

However, I noticed most (if not all) third party bundles use a hard coded event_dispatcher service call. For example, the JMS/JobQueueBundle uses the following

$this->dispatcher = $this->getContainer()->get('event_dispatcher');

Events dispatched like this fire correctly, but the debug.event_dispatcher doesn't know about them, which means the Symfony web profiler will incorrectly list a called listener as uncalled. Additionally, it's not clear how a bundle author could avoid this, as they don't have the advantage of generating a container file and the HTTP Kernel object doesn't expose an accessor for the protected dispatcher object.

So, is this a bug in Symfony?

Or is the event_dispatcher service only intended for Kernel events, meaning all those bundle authors are misusing it?

Or (the most likely candidate), is it something else I'm missing or haven't considered?

like image 828
Alan Storm Avatar asked Jan 16 '14 23:01

Alan Storm


People also ask

What is event dispatcher in Symfony?

The EventDispatcher component provides tools that allow your application components to communicate with each other by dispatching events and listening to them.

What is event dispatcher?

Event Dispatchers are an Actor communication method where one Actor dispatches an event and other Actors that are listening to that event are notified.

What is event in Symfony?

During the execution of a Symfony application, lots of event notifications are triggered. Your application can listen to these notifications and respond to them by executing any piece of code. Symfony triggers several events related to the kernel while processing the HTTP Request.

What is dispatcher component?

The Dispatcher component balances traffic among your servers through a unique combination of load balancing and management software.


1 Answers

It looks like the scenario I described above doesn't apply to that latest version of Symfony (2.4.1). Specifically, in 2.4.1, the generated app container file

app/cache/dev/appDevDebugProjectContainer.php

contains the following

$this->aliases = array(
    //...
    'event_dispatcher' => 'debug.event_dispatcher',
    //...
);

That is, unlike the Symfony 2.3.6 project I was working on, the event_dispatcher service has been aliased to the debug.event_dispatcher service (when Symfony runs in development mode). This means when other bundles ask for an event_dispatcher service in dev mode, they're really getting a debug.event_dispatcher service. This lets the the debug.event_dispatcher know about all the events, and it can correctly report on which ones were dispatched.

While it's not a concrete answer, it does indicate the Symfony team was/is aware of the issue, which leads me to believe it's their intention for Bundle developers to use the event_dispatch service fro their own events.

like image 52
Alan Storm Avatar answered Sep 20 '22 20:09

Alan Storm