[Profiler] Minimize the number of Profile writes
squash squash
This commit is contained in:
parent
114bc14c21
commit
255127081a
@ -13,7 +13,9 @@ namespace Symfony\Component\HttpKernel\Debug;
|
|||||||
|
|
||||||
use Symfony\Component\HttpKernel\Debug\Stopwatch;
|
use Symfony\Component\HttpKernel\Debug\Stopwatch;
|
||||||
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
use Symfony\Component\HttpKernel\Log\LoggerInterface;
|
||||||
|
use Symfony\Component\HttpKernel\Profiler\Profile;
|
||||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||||
|
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\EventDispatcher\Event;
|
use Symfony\Component\EventDispatcher\Event;
|
||||||
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
|
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
|
||||||
@ -30,6 +32,7 @@ class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatch
|
|||||||
private $called;
|
private $called;
|
||||||
private $stopwatch;
|
private $stopwatch;
|
||||||
private $priorities;
|
private $priorities;
|
||||||
|
private $profiler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -83,11 +86,18 @@ class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatch
|
|||||||
case 'kernel.response':
|
case 'kernel.response':
|
||||||
$token = $event->getResponse()->headers->get('X-Debug-Token');
|
$token = $event->getResponse()->headers->get('X-Debug-Token');
|
||||||
$this->stopwatch->stopSection($token);
|
$this->stopwatch->stopSection($token);
|
||||||
$this->updateProfile($token);
|
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
|
||||||
|
// 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;
|
break;
|
||||||
case 'kernel.terminate':
|
case 'kernel.terminate':
|
||||||
$this->stopwatch->stopSection($token);
|
$this->stopwatch->stopSection($token);
|
||||||
$this->updateProfile($token);
|
// 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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -255,28 +265,41 @@ class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatch
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the profile data.
|
* Updates the stopwatch data in the profile hierarchy.
|
||||||
*
|
*
|
||||||
* @param string $token Profile token
|
* @param string $token Profile token
|
||||||
|
* @param Boolean $updateChildren Whether to update the children altogether
|
||||||
*/
|
*/
|
||||||
private function updateProfile($token)
|
private function updateProfiles($token, $updateChildren)
|
||||||
{
|
{
|
||||||
if (!$this->getContainer()->has('profiler')) {
|
if (!$this->getContainer()->has('profiler')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$profiler = $this->getContainer()->get('profiler');
|
$this->profiler = $this->getContainer()->get('profiler');
|
||||||
if (!$profile = $profiler->loadProfile($token)) {
|
|
||||||
|
if (!$profile = $this->profiler->loadProfile($token)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$profile->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($token));
|
$this->saveStopwatchInfoInProfile($profile, $updateChildren);
|
||||||
$profiler->saveProfile($profile);
|
}
|
||||||
|
|
||||||
// children
|
/**
|
||||||
|
* Update the profiles with the timing info and saves them.
|
||||||
|
*
|
||||||
|
* @param Profile $profile The root profile
|
||||||
|
* @param Boolean $updateChildren Whether to update the children altogether
|
||||||
|
*/
|
||||||
|
private function saveStopwatchInfoInProfile(Profile $profile, $updateChildren)
|
||||||
|
{
|
||||||
|
$profile->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($profile->getToken()));
|
||||||
|
$this->profiler->saveProfile($profile);
|
||||||
|
|
||||||
|
if ($updateChildren) {
|
||||||
foreach ($profile->getChildren() as $child) {
|
foreach ($profile->getChildren() as $child) {
|
||||||
$child->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($child->getToken()));
|
$this->saveStopwatchInfoInProfile($child, true);
|
||||||
$profiler->saveProfile($child);
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
|||||||
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
|
||||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||||
use Symfony\Component\HttpKernel\KernelEvents;
|
use Symfony\Component\HttpKernel\KernelEvents;
|
||||||
|
use Symfony\Component\HttpKernel\Profiler\Profile;
|
||||||
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
use Symfony\Component\HttpKernel\Profiler\Profiler;
|
||||||
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
|
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
|
||||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||||
@ -34,6 +35,7 @@ class ProfilerListener implements EventSubscriberInterface
|
|||||||
protected $exception;
|
protected $exception;
|
||||||
protected $children;
|
protected $children;
|
||||||
protected $requests;
|
protected $requests;
|
||||||
|
protected $profiles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@ -50,6 +52,7 @@ class ProfilerListener implements EventSubscriberInterface
|
|||||||
$this->onlyException = (Boolean) $onlyException;
|
$this->onlyException = (Boolean) $onlyException;
|
||||||
$this->onlyMasterRequests = (Boolean) $onlyMasterRequests;
|
$this->onlyMasterRequests = (Boolean) $onlyMasterRequests;
|
||||||
$this->children = new \SplObjectStorage();
|
$this->children = new \SplObjectStorage();
|
||||||
|
$this->profiles = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -99,6 +102,16 @@ class ProfilerListener implements EventSubscriberInterface
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->profiles[] = $profile;
|
||||||
|
|
||||||
|
if (null !== $exception) {
|
||||||
|
foreach ($this->profiles as $profile) {
|
||||||
|
$this->profiler->saveProfile($profile);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// keep the profile as the child of its parent
|
// keep the profile as the child of its parent
|
||||||
if (!$master) {
|
if (!$master) {
|
||||||
array_pop($this->requests);
|
array_pop($this->requests);
|
||||||
@ -109,17 +122,16 @@ class ProfilerListener implements EventSubscriberInterface
|
|||||||
$this->children[$parent] = $profiles;
|
$this->children[$parent] = $profiles;
|
||||||
}
|
}
|
||||||
|
|
||||||
// store the profile and its children
|
|
||||||
if (isset($this->children[$request])) {
|
if (isset($this->children[$request])) {
|
||||||
foreach ($this->children[$request] as $child) {
|
foreach ($this->children[$request] as $child) {
|
||||||
$child->setParent($profile);
|
|
||||||
$profile->addChild($child);
|
$profile->addChild($child);
|
||||||
$this->profiler->saveProfile($child);
|
|
||||||
}
|
}
|
||||||
$this->children[$request] = array();
|
$this->children[$request] = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->profiler->saveProfile($profile);
|
if ($master) {
|
||||||
|
$this->saveProfiles($profile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static public function getSubscribedEvents()
|
static public function getSubscribedEvents()
|
||||||
@ -128,9 +140,21 @@ class ProfilerListener implements EventSubscriberInterface
|
|||||||
// kernel.request must be registered as early as possible to not break
|
// kernel.request must be registered as early as possible to not break
|
||||||
// when an exception is thrown in any other kernel.request listener
|
// when an exception is thrown in any other kernel.request listener
|
||||||
KernelEvents::REQUEST => array('onKernelRequest', 1024),
|
KernelEvents::REQUEST => array('onKernelRequest', 1024),
|
||||||
|
|
||||||
KernelEvents::RESPONSE => array('onKernelResponse', -100),
|
KernelEvents::RESPONSE => array('onKernelResponse', -100),
|
||||||
KernelEvents::EXCEPTION => 'onKernelException',
|
KernelEvents::EXCEPTION => 'onKernelException',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the profile hierarchy.
|
||||||
|
*
|
||||||
|
* @param Profile $profile The root profile
|
||||||
|
*/
|
||||||
|
private function saveProfiles(Profile $profile)
|
||||||
|
{
|
||||||
|
$this->profiler->saveProfile($profile);
|
||||||
|
foreach ($profile->getChildren() as $profile) {
|
||||||
|
$this->saveProfiles($profile);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user