8000 [Profiler] Minimize the number of Profile writes · jeremymarc/symfony@2551270 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2551270

Browse files
committed
[Profiler] Minimize the number of Profile writes
squash squash
1 parent 114bc14 commit 2551270

File tree

2 files changed

+65
-18
lines changed

2 files changed

+65
-18
lines changed

src/Symfony/Component/HttpKernel/Debug/ContainerAwareTraceableEventDispatcher.php

Lines changed: 36 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@
1313

1414
use Symfony\Component\HttpKernel\Debug\Stopwatch;
1515
use Symfony\Component\HttpKernel\Log\LoggerInterface;
16+
use Symfony\Component\HttpKernel\Profiler\Profile;
1617
use Symfony\Component\HttpKernel\Profiler\Profiler;
18+
use Symfony\Component\HttpKernel\HttpKernelInterface;
1719
use Symfony\Component\DependencyInjection\ContainerInterface;
1820
use Symfony\Component\EventDispatcher\Event;
1921
use Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher;
@@ -30,6 +32,7 @@ class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatch
3032
private $called;
3133
private $stopwatch;
3234
private $priorities;
35+
private $profiler;
3336

3437
/**
3538
* Constructor.
@@ -83,11 +86,18 @@ public function dispatch($eventName, Event $event = null)
8386
case 'kernel.response':
8487
$token = $event->getResponse()->headers->get('X-Debug-Token');
8588
$this->stopwatch->stopSection($token);
86-
$this->updateProfile($token);
89+
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
90+
// The profiles can only be updated once they have been created
91+
// that is after the 'kernel.response' event of the main request
92+
$this->updateProfiles($token, true);
93+
}
8794
break;
8895
case 'kernel.terminate':
8996
$this->stopwatch->stopSection($token);
90-
$this->updateProfile($token);
97+
// The children profiles have been updated by the previous 'kernel.response'
98+
// event. Only the root profile need to be updated with the 'kernel.terminate'
99+
// timing informations.
100+
$this->updateProfiles($token, false);
91101
break;
92102
}
93103

@@ -255,28 +265,41 @@ private function getListenerInfo($listener, $eventName)
255265
}
256266

257267
/**
258-
* Updates the profile data.
268+
* Updates the stopwatch data in the profile hierarchy.
259269
*
260-
* @param string $token Profile token
270+
* @param string $token Profile token
271+
* @param Boolean $updateChildren Whether to update the children altogether
261272
*/
262-
private function updateProfile($token)
273+
private function updateProfiles($token, $updateChildren)
263274
{
264275
if (!$this->getContainer()->has('profiler')) {
265276
return;
266277
}
267278

268-
$profiler = $this->getContainer()->get('profiler');
269-
if (!$profile = $profiler->loadProfile($token)) {
279+
$this->profiler = $this->getContainer()->get('profiler');
280+
281+
if (!$profile = $this->profiler->loadProfile($token)) {
270282
return;
271283
}
272284

273-
$profile->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($token));
274-
$profiler->saveProfile($profile);
285+
$this->saveStopwatchInfoInProfile($profile, $updateChildren);
286+
}
275287

276-
// children
277-
foreach ($profile->getChildren() as $child) {
278-
$child->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($child->getToken()));
279-
$profiler->saveProfile($child);
288+
/**
289+
* Update the profiles with the timing info and saves them.
290+
*
291+
* @param Profile $profile The root profile
292+
* @param Boolean $updateChildren Whether to update the children altogether
293+
*/
294+
private function saveStopwatchInfoInProfile(Profile $profile, $updateChildren)
295+
{
296+
$profile->getCollector('time')->setEvents($this->stopwatch->getSectionEvents($profile->getToken()));
297+
$this->profiler->saveProfile($profile);
298+
299+
if ($updateChildren) {
300+
foreach ($profile->getChildren() as $child) {
301+
$this->saveStopwatchInfoInProfile($child, true);
302+
}
280303
}
281304
}
282305

src/Symfony/Component/HttpKernel/EventListener/ProfilerListener.php

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
1717
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
1818
use Symfony\Component\HttpKernel\KernelEvents;
19+
use Symfony\Component\HttpKernel\Profiler\Profile;
1920
use Symfony\Component\HttpKernel\Profiler\Profiler;
2021
use Symfony\Component\HttpFoundation\RequestMatcherInterface;
2122
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -34,6 +35,7 @@ class ProfilerListener implements EventSubscriberInterface
3435
protected $exception;
3536
protected $children;
3637
protected $requests;
38+
protected $profiles;
3739

3840
/**
3941
* Constructor.
@@ -50,6 +52,7 @@ public function __construct(Profiler $profiler, RequestMatcherInterface $matcher
5052
$this->onlyException = (Boolean) $onlyException;
5153
$this->onlyMasterRequests = (Boolean) $onlyMasterRequests;
5254
$this->children = new \SplObjectStorage();
55+
$this->profiles = array();
5356
}
5457

5558
/**
@@ -99,6 +102,16 @@ public function onKernelResponse(FilterResponseEvent $event)
99102
return;
100103
}
101104

105+
$this->profiles[] = $profile;
106+
107+
if (null !== $exception) {
108+
foreach ($this->profiles as $profile) {
109+
$this->profiler->saveProfile($profile);
110+
}
111+
112+
return;
113+
}
114+
102115
// keep the profile as the child of its parent
103116
if (!$master) {
104117
array_pop($this->requests);
@@ -109,17 +122,16 @@ public function onKernelResponse(FilterResponseEvent $event)
109122
$this->children[$parent] = $profiles;
110123
}
111124

112-
// store the profile and its children
113125
if (isset($this->children[$request])) {
114126
foreach ($this->children[$request] as $child) {
115-
$child->setParent($profile);
116127
$profile->addChild($child);
117-
$this->profiler->saveProfile($child);
118128
}
119129
$this->children[$request] = array();
120130
}
121131

122-
$this->profiler->saveProfile($profile);
132+
if ($master) {
133+
$this->saveProfiles($profile);
134+
}
123135
}
124136

125137
static public function getSubscribedEvents()
@@ -128,9 +140,21 @@ static public function getSubscribedEvents()
128140
// kernel.request must be registered as early as possible to not break
129141
// when an exception is thrown in any other kernel.request listener
130142
KernelEvents::REQUEST => array('onKernelRequest', 1024),
131-
132143
KernelEvents::RESPONSE => array('onKernelResponse', -100),
133144
KernelEvents::EXCEPTION => 'onKernelException',
134145
);
135146
}
147+
148+
/**
149+
* Saves the profile hierarchy.
150+
*
151+
* @param Profile $profile The root profile
152+
*/
153+
private function saveProfiles(Profile $profile)
154+
{
155+
$this->profiler->saveProfile($profile);
156+
foreach ($profile->getChildren() as $profile) {
157+
$this->saveProfiles($profile);
158+
}
159+
}
136160
}

0 commit comments

Comments
 (0)
0