merged branch simon-n/master (PR #4321)

Commits
-------

46be121 added tokenDataExists() method to prevent loading complete profile structures upon writes

Discussion
----------

[HttpKernel] prevent loading complete profile structures upon writes

The abstract class "PdoProfilerStorage" uses its ::read() method to decide if a profiler record has to be updated or initially created upon a ::write() call. This possibly causes huge memory consumption, as ::read() recursively reads all existing profiles using ::createProfileFromData() calls. When handling many sub-request this may lead into either a "out of memory" or XDebug's "maximum nesting level reached" - whichever comes first.
To prevent this issue, I added a new protected method ::tokenDataExists() that simply checks whether a record for the token in question already exists in storage.

---------------------------------------------------------------------------

by travisbot at 2012-05-18T08:56:56Z

This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1364303) (merged 46be1212 into 1e15f210).
This commit is contained in:
Fabien Potencier 2012-05-22 12:03:11 +02:00
commit 148372be9e

View File

@ -92,7 +92,7 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
);
try {
if ($this->read($profile->getToken())) {
if ($this->tokenDataExists($profile->getToken())) {
$this->exec($db, 'UPDATE sf_profiler_data SET parent = :parent, data = :data, ip = :ip, method = :method, url = :url, time = :time, created_at = :created_at WHERE token = :token', $args);
} else {
$this->exec($db, 'INSERT INTO sf_profiler_data (token, parent, data, ip, method, url, time, created_at) VALUES (:token, :parent, :data, :ip, :method, :url, :time, :created_at)', $args);
@ -236,4 +236,20 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
return $profiles;
}
/**
* Returns whether data for the given token already exists in storage.
*
* @param string $token
* @return boolean
*/
protected function tokenDataExists($token)
{
$db = $this->initDb();
$tokenExists = $this->fetch($db, 'SELECT 1 FROM sf_profiler_data WHERE token = :token LIMIT 1', array(':token' => $token));
$this->close($db);
return !empty($tokenExists);
}
}