[HttpKernel] fixed profile parent/children for deep-nested requests
This commit is contained in:
parent
2aa1e4d351
commit
2b0af5e93b
@ -26,6 +26,7 @@
|
||||
<service id="profiler_listener" class="%profiler_listener.class%">
|
||||
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" priority="-100" />
|
||||
<tag name="kernel.event_listener" event="kernel.exception" method="onKernelException" />
|
||||
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" />
|
||||
<argument type="service" id="profiler" />
|
||||
<argument type="service" id="profiler.request_matcher" on-invalid="null" />
|
||||
<argument>%profiler_listener.only_exceptions%</argument>
|
||||
|
@ -32,6 +32,7 @@ class ProfilerListener
|
||||
protected $onlyMasterRequests;
|
||||
protected $exception;
|
||||
protected $children;
|
||||
protected $requests;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -47,7 +48,7 @@ class ProfilerListener
|
||||
$this->matcher = $matcher;
|
||||
$this->onlyException = (Boolean) $onlyException;
|
||||
$this->onlyMasterRequests = (Boolean) $onlyMasterRequests;
|
||||
$this->children = array();
|
||||
$this->children = new \SplObjectStorage();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,6 +65,11 @@ class ProfilerListener
|
||||
$this->exception = $event->getException();
|
||||
}
|
||||
|
||||
public function onKernelRequest(GetResponseEvent $event)
|
||||
{
|
||||
$this->requests[] = $event->getRequest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the onKernelResponse event.
|
||||
*
|
||||
@ -87,18 +93,35 @@ class ProfilerListener
|
||||
return;
|
||||
}
|
||||
|
||||
if ($profile = $this->profiler->collect($event->getRequest(), $event->getResponse(), $exception)) {
|
||||
if ($master) {
|
||||
foreach ($this->children as $child) {
|
||||
$child->setParent($profile);
|
||||
$profile->addChild($child);
|
||||
$this->profiler->saveProfile($child);
|
||||
}
|
||||
$this->profiler->saveProfile($profile);
|
||||
$this->children = array();
|
||||
} else {
|
||||
$this->children[] = $profile;
|
||||
}
|
||||
if (!$profile = $this->profiler->collect($event->getRequest(), $event->getResponse(), $exception)) {
|
||||
return;
|
||||
}
|
||||
|
||||
array_pop($this->requests);
|
||||
|
||||
// keep the profile as the child of its parent
|
||||
if (!$master) {
|
||||
$parent = $this->requests[count($this->requests) - 1];
|
||||
if (!isset($this->children[$parent])) {
|
||||
$profiles = array($profile);
|
||||
} else {
|
||||
$profiles = $this->children[$parent];
|
||||
$profiles[] = $profile;
|
||||
}
|
||||
|
||||
$this->children[$parent] = $profiles;
|
||||
}
|
||||
|
||||
// store the profile and its children
|
||||
if (isset($this->children[$event->getRequest()])) {
|
||||
foreach ($this->children[$event->getRequest()] as $child) {
|
||||
$child->setParent($profile);
|
||||
$profile->addChild($child);
|
||||
$this->profiler->saveProfile($child);
|
||||
}
|
||||
$this->children[$event->getRequest()] = array();
|
||||
}
|
||||
|
||||
$this->profiler->saveProfile($profile);
|
||||
}
|
||||
}
|
||||
|
@ -90,13 +90,25 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
|
||||
':time' => $profile->getTime(),
|
||||
':created_at' => time(),
|
||||
);
|
||||
try {
|
||||
$this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, url, time, created_at) VALUES (:token, :parent, :data, :ip, :url, :time, :created_at)', $args);
|
||||
$this->cleanup();
|
||||
$status = true;
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
|
||||
if ($this->read($profile->getToken())) {
|
||||
try {
|
||||
$this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, url = :url, time = :time, created_at = :created_at WHERE token = :token', $args);
|
||||
$this->cleanup();
|
||||
$status = true;
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
$this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, url, time, created_at) VALUES (:token, :parent, :data, :ip, :url, :time, :created_at)', $args);
|
||||
$this->cleanup();
|
||||
$status = true;
|
||||
} catch (\Exception $e) {
|
||||
$status = false;
|
||||
}
|
||||
}
|
||||
|
||||
$this->close($db);
|
||||
|
||||
return $status;
|
||||
|
@ -72,9 +72,14 @@ class SqliteProfilerStorageTest extends \PHPUnit_Framework_TestCase
|
||||
public function testStoreDuplicateToken()
|
||||
{
|
||||
$profile = new Profile('token');
|
||||
$profile->setUrl('http://example.com/');
|
||||
|
||||
$this->assertTrue(true === self::$storage->write($profile), '->write() returns true when the token is unique');
|
||||
$this->assertTrue(false === self::$storage->write($profile), '->write() return false when the token is already present in the DB');
|
||||
$this->assertTrue(self::$storage->write($profile), '->write() returns true when the token is unique');
|
||||
|
||||
$profile->setUrl('http://example.net/');
|
||||
|
||||
$this->assertTrue(self::$storage->write($profile), '->write() returns true when the token is already present in the DB');
|
||||
$this->assertEquals('http://example.net/', self::$storage->read('token')->getUrl(), '->write() overwrites the current profile data');
|
||||
}
|
||||
|
||||
public function testRetrieveByIp()
|
||||
|
Reference in New Issue
Block a user