Permalink
Browse files

feature #24289 [FrameworkBundle][HttpKernel] Reset profiler (derrabus)

This PR was merged into the 3.4 branch.

Discussion
----------

[FrameworkBundle][HttpKernel] Reset profiler

| Q             | A
| ------------- | ---
| Branch?       | 3.4
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | #18244
| License       | MIT
| Doc PR        | N/A

This PR adds the ability to reset the profiler between requests. Furthermore, the profiler service has been tagged with the new `kernel.reset` tag from #24155. For this, I had to readd the ability to define multiple reset methods for a service.

Note: This PR requires twigphp/Twig#2560.

Commits
-------

8c39bf7 Reset profiler.
  • Loading branch information...
fabpot committed Oct 5, 2017
2 parents d6b68e1 + 8c39bf7 commit 86684f1c07144e4253e200e10463b03359cfd253
Showing with 426 additions and 37 deletions.
  1. +12 −2 UPGRADE-3.4.md
  2. +8 −2 UPGRADE-4.0.md
  3. +1 −1 composer.json
  4. +14 −0 src/Symfony/Bridge/Doctrine/DataCollector/DoctrineDataCollector.php
  5. +14 −0 src/Symfony/Bridge/Doctrine/Tests/DataCollector/DoctrineDataCollectorTest.php
  6. +10 −0 src/Symfony/Bridge/Monolog/Logger.php
  7. +9 −0 src/Symfony/Bridge/Monolog/Processor/DebugProcessor.php
  8. +13 −0 src/Symfony/Bridge/Monolog/Tests/LoggerTest.php
  9. +10 −0 src/Symfony/Bridge/Twig/DataCollector/TwigDataCollector.php
  10. +1 −1 src/Symfony/Bridge/Twig/composer.json
  11. +3 −3 src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
  12. +8 −0 src/Symfony/Bundle/SecurityBundle/DataCollector/SecurityDataCollector.php
  13. +9 −0 src/Symfony/Component/Cache/DataCollector/CacheDataCollector.php
  14. +5 −0 src/Symfony/Component/EventDispatcher/CHANGELOG.md
  15. +5 −0 src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcher.php
  16. +2 −0 src/Symfony/Component/EventDispatcher/Debug/TraceableEventDispatcherInterface.php
  17. +15 −0 src/Symfony/Component/EventDispatcher/Tests/Debug/TraceableEventDispatcherTest.php
  18. +11 −5 src/Symfony/Component/Form/Extension/DataCollector/FormDataCollector.php
  19. +30 −0 src/Symfony/Component/Form/Tests/Extension/DataCollector/FormDataCollectorTest.php
  20. +3 −1 src/Symfony/Component/HttpKernel/CHANGELOG.md
  21. +5 −0 src/Symfony/Component/HttpKernel/DataCollector/AjaxDataCollector.php
  22. +8 −0 src/Symfony/Component/HttpKernel/DataCollector/ConfigDataCollector.php
  23. +2 −0 src/Symfony/Component/HttpKernel/DataCollector/DataCollectorInterface.php
  24. +16 −0 src/Symfony/Component/HttpKernel/DataCollector/EventDataCollector.php
  25. +8 −0 src/Symfony/Component/HttpKernel/DataCollector/ExceptionDataCollector.php
  26. +15 −0 src/Symfony/Component/HttpKernel/DataCollector/LoggerDataCollector.php
  27. +12 −4 src/Symfony/Component/HttpKernel/DataCollector/MemoryDataCollector.php
  28. +6 −0 src/Symfony/Component/HttpKernel/DataCollector/RequestDataCollector.php
  29. +15 −7 src/Symfony/Component/HttpKernel/DataCollector/RouterDataCollector.php
  30. +8 −0 src/Symfony/Component/HttpKernel/DataCollector/TimeDataCollector.php
  31. +2 −0 src/Symfony/Component/HttpKernel/Log/DebugLoggerInterface.php
  32. +24 −1 src/Symfony/Component/HttpKernel/Profiler/Profiler.php
  33. +19 −0 src/Symfony/Component/HttpKernel/Tests/DataCollector/ExceptionDataCollectorTest.php
  34. +20 −2 src/Symfony/Component/HttpKernel/Tests/DataCollector/LoggerDataCollectorTest.php
  35. +5 −0 src/Symfony/Component/HttpKernel/Tests/Fixtures/DataCollector/CloneVarDataCollector.php
  36. +4 −0 src/Symfony/Component/HttpKernel/Tests/Fixtures/TestEventDispatcher.php
  37. +14 −0 src/Symfony/Component/HttpKernel/Tests/Profiler/ProfilerTest.php
  38. +8 −0 src/Symfony/Component/Translation/DataCollector/TranslationDataCollector.php
  39. +19 −6 src/Symfony/Component/Validator/DataCollector/ValidatorDataCollector.php
  40. +27 −0 src/Symfony/Component/Validator/Tests/DataCollector/ValidatorDataCollectorTest.php
  41. +6 −2 src/Symfony/Component/Validator/Validator/TraceableValidator.php
View
@@ -63,6 +63,12 @@ Debug
* Support for stacked errors in the `ErrorHandler` is deprecated and will be removed in Symfony 4.0.
EventDispatcher
---------------
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method
is deprecated and will be unsupported in 4.0.
Filesystem
----------
@@ -270,6 +276,10 @@ HttpKernel
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been deprecated and will be removed in 4.0.
* Implementing `DataCollectorInterface` without a `reset()` method has been deprecated and will be unsupported in 4.0.
* Implementing `DebugLoggerInterface` without a `clear()` method has been deprecated and will be unsupported in 4.0.
* The `ChainCacheClearer::add()` method has been deprecated and will be removed in 4.0,
inject the list of clearers as a constructor argument instead.
@@ -320,11 +330,11 @@ SecurityBundle
* Deprecated the HTTP digest authentication: `HttpDigestFactory` will be removed in 4.0.
Use another authentication system like `http_basic` instead.
* Deprecated setting the `switch_user.stateless` option to false when the firewall is `stateless`.
Setting it to false will have no effect in 4.0.
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
Using the first configured provider is deprecated since 3.4 and will throw an exception on 4.0.
Explicitly configure the provider to use on your firewalls.
View
@@ -192,6 +192,8 @@ EventDispatcher
* The `ContainerAwareEventDispatcher` class has been removed.
Use `EventDispatcher` with closure factories instead.
* The `reset()` method has been added to `TraceableEventDispatcherInterface`.
ExpressionLanguage
------------------
@@ -611,6 +613,10 @@ HttpKernel
* The `Symfony\Component\HttpKernel\Config\EnvParametersResource` class has been removed.
* The `reset()` method has been added to `Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface`.
* The `clear()` method has been added to `Symfony\Component\HttpKernel\Log\DebugLoggerInterface`.
* The `ChainCacheClearer::add()` method has been removed,
inject the list of clearers as a constructor argument instead.
@@ -693,10 +699,10 @@ SecurityBundle
* Removed the HTTP digest authentication system. The `HttpDigestFactory` class
has been removed. Use another authentication system like `http_basic` instead.
* The `switch_user.stateless` option is now always true if the firewall is stateless.
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
* Not configuring explicitly the provider on a firewall is ambiguous when there is more than one registered provider.
The first configured provider is not used anymore and an exception is thrown instead.
Explicitly configure the provider to use on your firewalls.
View
@@ -20,7 +20,7 @@
"ext-xml": "*",
"doctrine/common": "~2.4",
"fig/link-util": "^1.0",
"twig/twig": "~1.34|~2.4",
"twig/twig": "^1.35|^2.4.4",
"psr/cache": "~1.0",
"psr/container": "^1.0",
"psr/link": "^1.0",
@@ -28,6 +28,10 @@ class DoctrineDataCollector extends DataCollector
private $registry;
private $connections;
private $managers;
/**
* @var DebugStack[]
*/
private $loggers = array();
public function __construct(ManagerRegistry $registry)
@@ -65,6 +69,16 @@ public function collect(Request $request, Response $response, \Exception $except
);
}
public function reset()
{
$this->data = array();
foreach ($this->loggers as $logger) {
$logger->queries = array();
$logger->currentQuery = 0;
}
}
public function getManagers()
{
return $this->data['managers'];
@@ -101,6 +101,20 @@ public function testCollectQueryWithNoParams()
$this->assertTrue($collectedQueries['default'][1]['explainable']);
}
public function testReset()
{
$queries = array(
array('sql' => 'SELECT * FROM table1', 'params' => array(), 'types' => array(), 'executionMS' => 1),
);
$c = $this->createCollector($queries);
$c->collect(new Request(), new Response());
$c->reset();
$c->collect(new Request(), new Response());
$this->assertEquals(array('default' => array()), $c->getQueries());
}
/**
* @dataProvider paramProvider
*/
@@ -45,6 +45,16 @@ public function countErrors()
return 0;
}
/**
* {@inheritdoc}
*/
public function clear()
{
if (($logger = $this->getDebugLogger()) && method_exists($logger, 'clear')) {
$logger->clear();
}
}
/**
* Returns a DebugLoggerInterface instance if one is registered with this logger.
*
@@ -55,4 +55,13 @@ public function countErrors()
{
return $this->errorCount;
}
/**
* {@inheritdoc}
*/
public function clear()
{
$this->records = array();
$this->errorCount = 0;
}
}
@@ -128,4 +128,17 @@ public function testGetLogsWithDebugProcessor2()
$this->assertEquals('test', $record['message']);
$this->assertEquals(Logger::INFO, $record['priority']);
}
public function testClear()
{
$handler = new TestHandler();
$logger = new Logger('test', array($handler));
$logger->pushProcessor(new DebugProcessor());
$logger->addInfo('test');
$logger->clear();
$this->assertEmpty($logger->getLogs());
$this->assertSame(0, $logger->countErrors());
}
}
@@ -44,6 +44,16 @@ public function collect(Request $request, Response $response, \Exception $except
{
}
/**
* {@inheritdoc}
*/
public function reset()
{
$this->profile->reset();
$this->computed = null;
$this->data = array();
}
/**
* {@inheritdoc}
*/
@@ -17,7 +17,7 @@
],
"require": {
"php": "^5.5.9|>=7.0.8",
"twig/twig": "~1.34|~2.4"
"twig/twig": "^1.35|^2.4.4"
},
"require-dev": {
"fig/link-util": "^1.0",
@@ -609,9 +609,9 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $
}
}
if (!$config['collect']) {
$container->getDefinition('profiler')->addMethodCall('disable', array());
}
$container->getDefinition('profiler')
->addArgument($config['collect'])
->addTag('kernel.reset', array('method' => 'reset'));
}
/**
@@ -203,6 +203,14 @@ public function collect(Request $request, Response $response, \Exception $except
}
}
/**
* {@inheritdoc}
*/
public function reset()
{
$this->data = array();
}
public function lateCollect()
{
$this->data = $this->cloneVar($this->data);
@@ -53,6 +53,15 @@ public function collect(Request $request, Response $response, \Exception $except
$this->data['total']['statistics'] = $this->calculateTotalStatistics();
}
public function reset()
{
$this->data = array();
foreach ($this->instances as $instance) {
// Calling getCalls() will clear the calls.
$instance->getCalls();
}
}
public function lateCollect()
{
$this->data = $this->cloneVar($this->data);
@@ -1,6 +1,11 @@
CHANGELOG
=========
3.4.0
-----
* Implementing `TraceableEventDispatcherInterface` without the `reset()` method has been deprecated.
3.3.0
-----
@@ -212,6 +212,11 @@ public function getNotCalledListeners()
return $notCalled;
}
public function reset()
{
$this->called = array();
}
/**
* Proxies all method calls to the original event dispatcher.
*
@@ -15,6 +15,8 @@
/**
* @author Fabien Potencier <fabien@symfony.com>
*
* @method reset() Resets the trace.
*/
interface TraceableEventDispatcherInterface extends EventDispatcherInterface
{
@@ -124,6 +124,21 @@ public function testGetCalledListeners()
$this->assertEquals(array(), $tdispatcher->getNotCalledListeners());
}
public function testClearCalledListeners()
{
$tdispatcher = new TraceableEventDispatcher(new EventDispatcher(), new Stopwatch());
$tdispatcher->addListener('foo', function () {}, 5);
$tdispatcher->dispatch('foo');
$tdispatcher->reset();
$listeners = $tdispatcher->getNotCalledListeners();
$this->assertArrayHasKey('stub', $listeners['foo.closure']);
unset($listeners['foo.closure']['stub']);
$this->assertEquals(array(), $tdispatcher->getCalledListeners());
$this->assertEquals(array('foo.closure' => array('event' => 'foo', 'pretty' => 'closure', 'priority' => 5)), $listeners);
}
public function testGetCalledListenersNested()
{
$tdispatcher = null;
@@ -72,12 +72,9 @@ class FormDataCollector extends DataCollector implements FormDataCollectorInterf
public function __construct(FormDataExtractorInterface $dataExtractor)
{
$this->dataExtractor = $dataExtractor;
$this->data = array(
'forms' => array(),
'forms_by_hash' => array(),
'nb_errors' => 0,
);
$this->hasVarDumper = class_exists(ClassStub::class);
$this->reset();
}
/**
@@ -87,6 +84,15 @@ public function collect(Request $request, Response $response, \Exception $except
{
}
public function reset()
{
$this->data = array(
'forms' => array(),
'forms_by_hash' => array(),
'nb_errors' => 0,
);
}
/**
* {@inheritdoc}
*/
@@ -695,6 +695,36 @@ public function testCollectSubmittedDataExpandedFormsErrors()
$this->assertFalse(isset($child21Data['has_children_error']), 'The leaf data does not contains "has_children_error" property.');
}
public function testReset()
{
$form = $this->createForm('my_form');
$this->dataExtractor->expects($this->any())
->method('extractConfiguration')
->will($this->returnValue(array()));
$this->dataExtractor->expects($this->any())
->method('extractDefaultData')
->will($this->returnValue(array()));
$this->dataExtractor->expects($this->any())
->method('extractSubmittedData')
->with($form)
->will($this->returnValue(array('errors' => array('baz'))));
$this->dataCollector->buildPreliminaryFormTree($form);
$this->dataCollector->collectSubmittedData($form);
$this->dataCollector->reset();
$this->assertSame(
array(
'forms' => array(),
'forms_by_hash' => array(),
'nb_errors' => 0,
),
$this->dataCollector->getData()
);
}
private function createForm($name)
{
$builder = new FormBuilder($name, null, $this->dispatcher, $this->factory);
@@ -14,7 +14,9 @@ CHANGELOG
* deprecated the `ChainCacheClearer::add()` method
* deprecated the `CacheaWarmerAggregate::add()` and `setWarmers()` methods
* made `CacheWarmerAggregate` and `ChainCacheClearer` classes final
* added the possibility to reset the profiler to its initial state
* deprecated data collectors without a `reset()` method
* deprecated implementing `DebugLoggerInterface` without a `clear()` method
3.3.0
-----
@@ -26,6 +26,11 @@ public function collect(Request $request, Response $response, \Exception $except
// all collecting is done client side
}
public function reset()
{
// all collecting is done client side
}
public function getName()
{
return 'ajax';
Oops, something went wrong.

0 comments on commit 86684f1

Please sign in to comment.