More Notes on Symfony Event Dispatch

As hinted at by the last post, I've spent more of my "Oro Time" this week mired in Symfony's event dispatcher. There's a few other things I've found that are worth sharing.

First, the web profiler appears to have a bug where it will incorrectly list a called observer as uncalled. Or it may be that the event dispatcher that ships with Symfony is only intended for kernel events and bundle authors are misusing it for their own event systems.

Speaking of kernel events — my initial event debugging indicated the OroCRM beta has over 450 kernel.request listeners, over 200 kernel.response listeners, and near another 200 kernel.request listeners. I haven't done a lot of Symfony 2 development, but that seemed excessive. Fortunately, it was a misdiagnosis on my part. The special TraceableEventDispatcher dispatcher sets and resets it's listeners in the preDispatch method

#File: vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php
private function preDispatch($eventName, Event $event)
{
    //...
    foreach ($listeners as $listener) {
        $this->dispatcher->removeListener($eventName, $listener);
        $wrapped = $this->wrapListener($eventName, $listener);
        $this->wrappedListeners[$this->id][$wrapped] = $listener;
        $this->dispatcher->addListener($eventName, $wrapped);
    }
    //...    
}

This, combined with my simple debugging in addListener led me to think there were a crazy number of listeners setup.

Finally, one reason it was plausible Symfony had that many listeners setup is the system includes the ability for an event to stop propagation. If you call stopPropagation on your event object

$event->stopPropagation();

you're telling Symfony to skip running future listeners for this event dispatch. I'm not sure I like this feature in a modular full stack framework's event system as it gives a single bundle developer the ability to radically interfere with other bundle developer's listeners — but the feature is there, so make sure you include it in your debugging regime.