[HttpKernel] fixed profile parent/children for deep-nested requests

This commit is contained in:
Fabien Potencier 2011-10-17 02:32:06 +02:00
parent 2aa1e4d351
commit 2b0af5e93b
4 changed files with 62 additions and 21 deletions

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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()