Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Decoupled TraceableEventDispatcher from the Profiler #9170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 30, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@

<service id="data_collector.events" class="%data_collector.events.class%" public="false">
<tag name="data_collector" template="@WebProfiler/Collector/events.html.twig" id="events" priority="255" />
<argument type="service" id="event_dispatcher" on-invalid="ignore" />
</service>

<service id="data_collector.logger" class="%data_collector.logger.class%" public="false">
Expand All @@ -45,6 +46,7 @@
<service id="data_collector.time" class="%data_collector.time.class%" public="false">
<tag name="data_collector" template="@WebProfiler/Collector/time.html.twig" id="time" priority="255" />
<argument type="service" id="kernel" on-invalid="ignore" />
<argument type="service" id="debug.stopwatch" on-invalid="ignore" />
</service>

<service id="data_collector.memory" class="%data_collector.memory.class%" public="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
<argument type="service" id="event_dispatcher" />
<argument type="service" id="debug.stopwatch" />
<argument type="service" id="logger" on-invalid="null" />
<call method="setProfiler"><argument type="service" id="profiler" on-invalid="null" /></call>
</service>

<service id="debug.controller_resolver" class="%debug.controller_resolver.class%">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<argument type="service" id="profiler.request_matcher" on-invalid="null" />
<argument>%profiler_listener.only_exceptions%</argument>
<argument>%profiler_listener.only_master_requests%</argument>
<argument type="service" id="request_stack" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,26 @@

namespace Symfony\Component\HttpKernel\DataCollector;

use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;

/**
* EventDataCollector.
*
* @author Fabien Potencier <[email protected]>
*/
class EventDataCollector extends DataCollector
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
{
protected $dispatcher;

public function __construct(EventDispatcherInterface $dispatcher = null)
{
$this->dispatcher = $dispatcher;
}

/**
* {@inheritdoc}
*/
Expand All @@ -33,6 +42,14 @@ public function collect(Request $request, Response $response, \Exception $except
);
}

public function lateCollect()
{
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
$this->setCalledListeners($this->dispatcher->getCalledListeners());
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners());
}
}

/**
* Sets the called listeners.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\HttpKernel\DataCollector;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

/**
* LateDataCollectorInterface.
*
* @author Fabien Potencier <[email protected]>
*/
interface LateDataCollectorInterface
{
/**
* Collects data as late as possible.
*/
public function lateCollect();
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ public function __construct($logger = null)
}
}

/**
* {@inheritdoc}
*/
public function collect(Request $request, Response $response, \Exception $exception = null)
{
// everything is done as late as possible
}

/**
* {@inheritdoc}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Symfony\Component\HttpKernel\DataCollector;

use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

Expand All @@ -19,7 +20,7 @@
*
* @author Fabien Potencier <[email protected]>
*/
class MemoryDataCollector extends DataCollector
class MemoryDataCollector extends DataCollector implements LateDataCollectorInterface
{
public function __construct()
{
Expand All @@ -37,6 +38,14 @@ public function collect(Request $request, Response $response, \Exception $except
$this->updateMemoryUsage();
}

/**
* {@inheritdoc}
*/
public function lateCollect()
{
$this->updateMemoryUsage();
}

/**
* Gets the memory.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,26 @@
namespace Symfony\Component\HttpKernel\DataCollector;

use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Stopwatch\Stopwatch;

/**
* TimeDataCollector.
*
* @author Fabien Potencier <[email protected]>
*/
class TimeDataCollector extends DataCollector
class TimeDataCollector extends DataCollector implements LateDataCollectorInterface
{
protected $kernel;
protected $stopwatch;

public function __construct(KernelInterface $kernel = null)
public function __construct(KernelInterface $kernel = null, $stopwatch = null)
{
$this->kernel = $kernel;
$this->stopwatch = $stopwatch;
}

/**
Expand All @@ -42,11 +46,23 @@ public function collect(Request $request, Response $response, \Exception $except
}

$this->data = array(
'token' => $response->headers->get('X-Debug-Token'),
'start_time' => $startTime * 1000,
'events' => array(),
);
}

/**
* {@inheritdoc}
*/
public function lateCollect()
{
if (null !== $this->stopwatch && isset($this->data['token'])) {
$this->setEvents($this->stopwatch->getSectionEvents($this->data['token']));
}
unset($this->data['token']);
}

/**
* Sets the request events.
*
Expand Down
80 changes: 13 additions & 67 deletions src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\HttpKernel\KernelEvents;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpKernel\Profiler\Profile;
use Symfony\Component\HttpKernel\Profiler\Profiler;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
Expand All @@ -33,7 +31,6 @@ class TraceableEventDispatcher implements EventDispatcherInterface, TraceableEve
private $logger;
private $called;
private $stopwatch;
private $profiler;
private $dispatcher;
private $wrappedListeners;
private $firstCalledEvent;
Expand All @@ -59,11 +56,16 @@ public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $sto
/**
* Sets the profiler.
*
* The traceable event dispatcher does not use the profiler anymore.
* The job is now done directly by the Profiler listener and the
* data collectors themselves.
*
* @param Profiler|null $profiler A Profiler instance
*
* @deprecated Deprecated since version 2.4, to be removed in 3.0.
*/
public function setProfiler(Profiler $profiler = null)
{
$this->profiler = $profiler;
}

/**
Expand Down Expand Up @@ -142,7 +144,9 @@ public function dispatch($eventName, Event $event = null)

unset($this->firstCalledEvent[$eventName]);

$e->stop();
if ($e->isStarted()) {
$e->stop();
}

$this->postDispatch($eventName, $event);

Expand Down Expand Up @@ -312,57 +316,6 @@ private function getListenerInfo($listener, $eventName)
return $info;
}

/**
* Updates the stopwatch data in the profile hierarchy.
*
* @param string $token Profile token
* @param Boolean $updateChildren Whether to update the children altogether
*/
private function updateProfiles($token, $updateChildren)
{
if (!$this->profiler || !$profile = $this->profiler->loadProfile($token)) {
return;
}

$this->saveInfoInProfile($profile, $updateChildren);
}

/**
* Update the profiles with the timing and events information and saves them.
*
* @param Profile $profile The root profile
* @param Boolean $updateChildren Whether to update the children altogether
*/
private function saveInfoInProfile(Profile $profile, $updateChildren)
{
try {
$collector = $profile->getCollector('memory');
$collector->updateMemoryUsage();
} catch (\InvalidArgumentException $e) {
}

try {
$collector = $profile->getCollector('time');
$collector->setEvents($this->stopwatch->getSectionEvents($profile->getToken()));
} catch (\InvalidArgumentException $e) {
}

try {
$collector = $profile->getCollector('events');
$collector->setCalledListeners($this->getCalledListeners());
$collector->setNotCalledListeners($this->getNotCalledListeners());
} catch (\InvalidArgumentException $e) {
}

$this->profiler->saveProfile($profile);

if ($updateChildren) {
foreach ($profile->getChildren() as $child) {
$this->saveInfoInProfile($child, true);
}
}
}

private function preDispatch($eventName, Event $event)
{
// wrap all listeners before they are called
Expand Down Expand Up @@ -411,23 +364,14 @@ private function postDispatch($eventName, Event $event)
case KernelEvents::RESPONSE:
$token = $event->getResponse()->headers->get('X-Debug-Token');
$this->stopwatch->stopSection($token);
if ($event->isMasterRequest()) {
// The profiles can only be updated once they have been created
// that is after the 'kernel.response' event of the main request
$this->updateProfiles($token, true);
}
break;
case KernelEvents::TERMINATE:
$token = $event->getResponse()->headers->get('X-Debug-Token');
// In the special case described in the `preDispatch` method above, the `$token` section
// does not exist, then closing it throws an exception which must be caught.
$token = $event->getResponse()->headers->get('X-Debug-Token');
try {
$this->stopwatch->stopSection($token);
} catch (\LogicException $e) {}
// The children profiles have been updated by the previous 'kernel.response'
// event. Only the root profile need to be updated with the 'kernel.terminate'
// timing informations.
$this->updateProfiles($token, false);
break;
}

Expand All @@ -448,7 +392,9 @@ private function wrapListener($eventName, $listener)

call_user_func($listener, $event, $eventName, $self);

$e->stop();
if ($e->isStarted()) {
$e->stop();
}

if ($event->isPropagationStopped()) {
$self->logSkippedListeners($eventName, $event, $listener);
Expand Down
Loading