13
13
14
14
use Symfony \Component \HttpKernel \Debug \Stopwatch ;
15
15
use Symfony \Component \HttpKernel \Log \LoggerInterface ;
16
+ use Symfony \Component \HttpKernel \Profiler \Profile ;
16
17
use Symfony \Component \HttpKernel \Profiler \Profiler ;
18
+ use Symfony \Component \HttpKernel \HttpKernelInterface ;
17
19
use Symfony \Component \DependencyInjection \ContainerInterface ;
18
20
use Symfony \Component \EventDispatcher \Event ;
19
21
use Symfony \Component \EventDispatcher \ContainerAwareEventDispatcher ;
@@ -30,6 +32,7 @@ class ContainerAwareTraceableEventDispatcher extends ContainerAwareEventDispatch
30
32
private $ called ;
31
33
private $ stopwatch ;
32
34
private $ priorities ;
35
+ private $ profiler ;
33
36
34
37
/**
35
38
* Constructor.
@@ -83,11 +86,18 @@ public function dispatch($eventName, Event $event = null)
83
86
case 'kernel.response ' :
84
87
$ token = $ event ->getResponse ()->headers ->get ('X-Debug-Token ' );
85
88
$ 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
+ }
87
94
break ;
88
95
case 'kernel.terminate ' :
89
96
$ 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 );
91
101
break ;
92
102
}
93
103
@@ -255,28 +265,41 @@ private function getListenerInfo($listener, $eventName)
255
265
}
256
266
257
267
/**
258
- * Updates the profile data.
268
+ * Updates the stopwatch data in the profile hierarchy .
259
269
*
260
- * @param string $token Profile token
270
+ * @param string $token Profile token
271
+ * @param Boolean $updateChildren Whether to update the children altogether
261
272
*/
262
- private function updateProfile ($ token )
273
+ private function updateProfiles ($ token, $ updateChildren )
263
274
{
264
275
if (!$ this ->getContainer ()->has ('profiler ' )) {
265
276
return ;
266
277
}
267
278
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 )) {
270
282
return ;
271
283
}
272
284
273
- $ profile -> getCollector ( ' time ' )-> setEvents ( $ this ->stopwatch -> getSectionEvents ( $ token ) );
274
- $ profiler -> saveProfile ( $ profile );
285
+ $ this ->saveStopwatchInfoInProfile ( $ profile , $ updateChildren );
286
+ }
275
287
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
+ }
280
303
}
281
304
}
282
305
0 commit comments