Skip to content

Commit ef0f6f1

Browse files
Merge pull request #247 from doctrine/slc
Second Level Cache
2 parents 7b1c579 + 7230705 commit ef0f6f1

13 files changed

+696
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Doctrine Bundle
5+
*
6+
* The code was originally distributed inside the Symfony framework.
7+
*
8+
* (c) Fabien Potencier <fabien@symfony.com>
9+
* (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy;
16+
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Input\InputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Doctrine\ORM\Tools\Console\Command\ClearCache\CollectionRegionCommand;
21+
22+
/**
23+
* Command to clear a collection cache region.
24+
*
25+
* @author Fabien Potencier <fabien@symfony.com>
26+
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
27+
*/
28+
class CollectionRegionDoctrineCommand extends CollectionRegionCommand
29+
{
30+
/**
31+
* {@inheritDoc}
32+
*/
33+
protected function configure()
34+
{
35+
parent::configure();
36+
37+
$this
38+
->setName('doctrine:cache:clear-collection-region')
39+
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
40+
;
41+
}
42+
43+
/**
44+
* {@inheritDoc}
45+
*/
46+
protected function execute(InputInterface $input, OutputInterface $output)
47+
{
48+
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
49+
50+
return parent::execute($input, $output);
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Doctrine Bundle
5+
*
6+
* The code was originally distributed inside the Symfony framework.
7+
*
8+
* (c) Fabien Potencier <fabien@symfony.com>
9+
* (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy;
16+
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Input\InputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Doctrine\ORM\Tools\Console\Command\ClearCache\EntityRegionCommand;
21+
22+
/**
23+
* Command to clear a entity cache region.
24+
*
25+
* @author Fabien Potencier <fabien@symfony.com>
26+
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
27+
*/
28+
class EntityRegionCacheDoctrineCommand extends EntityRegionCommand
29+
{
30+
/**
31+
* {@inheritDoc}
32+
*/
33+
protected function configure()
34+
{
35+
parent::configure();
36+
37+
$this
38+
->setName('doctrine:cache:clear-entity-region')
39+
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
40+
;
41+
}
42+
43+
/**
44+
* {@inheritDoc}
45+
*/
46+
protected function execute(InputInterface $input, OutputInterface $output)
47+
{
48+
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
49+
50+
return parent::execute($input, $output);
51+
}
52+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Doctrine Bundle
5+
*
6+
* The code was originally distributed inside the Symfony framework.
7+
*
8+
* (c) Fabien Potencier <fabien@symfony.com>
9+
* (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
10+
*
11+
* For the full copyright and license information, please view the LICENSE
12+
* file that was distributed with this source code.
13+
*/
14+
15+
namespace Doctrine\Bundle\DoctrineBundle\Command\Proxy;
16+
17+
use Symfony\Component\Console\Input\InputOption;
18+
use Symfony\Component\Console\Input\InputInterface;
19+
use Symfony\Component\Console\Output\OutputInterface;
20+
use Doctrine\ORM\Tools\Console\Command\ClearCache\QueryRegionCommand;
21+
22+
/**
23+
* Command to clear a query cache region.
24+
*
25+
* @author Fabien Potencier <fabien@symfony.com>
26+
* @author Fabio B. Silva <fabio.bat.silva@gmail.com>
27+
*/
28+
class QueryRegionCacheDoctrineCommand extends QueryRegionCommand
29+
{
30+
/**
31+
* {@inheritDoc}
32+
*/
33+
protected function configure()
34+
{
35+
parent::configure();
36+
37+
$this
38+
->setName('doctrine:cache:clear-query-region')
39+
->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
40+
;
41+
}
42+
43+
/**
44+
* {@inheritDoc}
45+
*/
46+
protected function execute(InputInterface $input, OutputInterface $output)
47+
{
48+
DoctrineCommandHelper::setApplicationEntityManager($this->getApplication(), $input->getOption('em'));
49+
50+
return parent::execute($input, $output);
51+
}
52+
}

DataCollector/DoctrineDataCollector.php

+98-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,22 @@ public function collect(Request $request, Response $response, \Exception $except
4444
{
4545
parent::collect($request, $response, $exception);
4646

47-
$errors = array();
47+
$errors = array();
4848
$entities = array();
49+
$caches = array(
50+
'enabled' => false,
51+
'log_enabled' => false,
52+
'counts' => array(
53+
'puts' => 0,
54+
'hits' => 0,
55+
'misses' => 0,
56+
),
57+
'regions' => array(
58+
'puts' => array(),
59+
'hits' => array(),
60+
'misses' => array(),
61+
),
62+
);
4963

5064
foreach ($this->registry->getManagers() as $name => $em) {
5165
$entities[$name] = array();
@@ -62,10 +76,62 @@ public function collect(Request $request, Response $response, \Exception $except
6276
$errors[$name][$class->getName()] = $classErrors;
6377
}
6478
}
79+
80+
/** @var $emConfig \Doctrine\ORM\Configuration */
81+
$emConfig = $em->getConfiguration();
82+
$slcEnabled = $emConfig->isSecondLevelCacheEnabled();
83+
84+
if ( ! $slcEnabled) {
85+
continue;
86+
}
87+
88+
$caches['enabled'] = true;
89+
90+
/** @var $cacheConfiguration \Doctrine\ORM\Cache\CacheConfiguration */
91+
/** @var $clacheLoggerChain \Doctrine\ORM\Cache\Logging\CacheLoggerChain */
92+
/** @var $cacheLoggerStats \Doctrine\ORM\Cache\Logging\StatisticsCacheLogger */
93+
$cacheConfiguration = $emConfig->getSecondLevelCacheConfiguration();
94+
$cacheLoggerChain = $cacheConfiguration->getCacheLogger();
95+
$cacheLoggerStats = $cacheLoggerChain->getLogger('statistics');
96+
97+
if ( ! $cacheLoggerStats) {
98+
continue;
99+
}
100+
101+
$caches['log_enabled'] = true;
102+
103+
$caches['counts']['puts'] += $cacheLoggerStats->getPutCount();
104+
$caches['counts']['hits'] += $cacheLoggerStats->getHitCount();
105+
$caches['counts']['misses'] += $cacheLoggerStats->getMissCount();
106+
107+
foreach ($cacheLoggerStats->getRegionsPut() as $key => $value) {
108+
if ( ! isset($caches['regions']['puts'][$key])) {
109+
$caches['regions']['puts'][$key] = 0;
110+
}
111+
112+
$caches['regions']['puts'][$key] += $value;
113+
}
114+
115+
foreach ($cacheLoggerStats->getRegionsHit() as $key => $value) {
116+
if ( ! isset($caches['regions']['hits'][$key])) {
117+
$caches['regions']['hits'][$key] = 0;
118+
}
119+
120+
$caches['regions']['hits'][$key] += $value;
121+
}
122+
123+
foreach ($cacheLoggerStats->getRegionsMiss() as $key => $value) {
124+
if ( ! isset($caches['regions']['misses'][$key])) {
125+
$caches['regions']['misses'][$key] = 0;
126+
}
127+
128+
$caches['regions']['misses'][$key] += $value;
129+
}
65130
}
66131

67132
$this->data['entities'] = $entities;
68-
$this->data['errors'] = $errors;
133+
$this->data['errors'] = $errors;
134+
$this->data['caches'] = $caches;
69135
}
70136

71137
public function getEntities()
@@ -78,6 +144,36 @@ public function getMappingErrors()
78144
return $this->data['errors'];
79145
}
80146

147+
public function getCacheHitsCount()
148+
{
149+
return $this->data['caches']['counts']['hits'];
150+
}
151+
152+
public function getCachePutsCount()
153+
{
154+
return $this->data['caches']['counts']['puts'];
155+
}
156+
157+
public function getCacheMissesCount()
158+
{
159+
return $this->data['caches']['counts']['misses'];
160+
}
161+
162+
public function getCacheEnabled()
163+
{
164+
return $this->data['caches']['enabled'];
165+
}
166+
167+
public function getCacheRegions()
168+
{
169+
return $this->data['caches']['regions'];
170+
}
171+
172+
public function getCacheCounts()
173+
{
174+
return $this->data['caches']['counts'];
175+
}
176+
81177
public function getInvalidEntityCount()
82178
{
83179
if (null === $this->invalidEntityCount) {

DependencyInjection/Configuration.php

+41
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,47 @@ private function getOrmEntityManagersNode()
438438
->scalarNode('entity_listener_resolver')->defaultNull()->end()
439439
->scalarNode('repository_factory')->defaultNull()->end()
440440
->end()
441+
->children()
442+
->arrayNode('second_level_cache')
443+
->children()
444+
->append($this->getOrmCacheDriverNode('region_cache_driver'))
445+
->scalarNode('region_lock_lifetime')->defaultValue(60)->end()
446+
->booleanNode('log_enabled')->defaultValue($this->debug)->end()
447+
->scalarNode('region_lifetime')->defaultValue(0)->end()
448+
->booleanNode('enabled')->defaultValue(true)->end()
449+
->scalarNode('factory')->end()
450+
->end()
451+
->fixXmlConfig('region')
452+
->children()
453+
->arrayNode('regions')
454+
->useAttributeAsKey('name')
455+
->prototype('array')
456+
->children()
457+
->append($this->getOrmCacheDriverNode('cache_driver'))
458+
->scalarNode('lock_path')->defaultValue('%kernel.cache_dir%/doctrine/orm/slc/filelock')->end()
459+
->scalarNode('lock_lifetime')->defaultValue(60)->end()
460+
->scalarNode('type')->defaultValue('default')->end()
461+
->scalarNode('lifetime')->defaultValue(0)->end()
462+
->scalarNode('service')->end()
463+
->scalarNode('name')->end()
464+
->end()
465+
->end()
466+
->end()
467+
->end()
468+
->fixXmlConfig('logger')
469+
->children()
470+
->arrayNode('loggers')
471+
->useAttributeAsKey('name')
472+
->prototype('array')
473+
->children()
474+
->scalarNode('name')->end()
475+
->scalarNode('service')->end()
476+
->end()
477+
->end()
478+
->end()
479+
->end()
480+
->end()
481+
->end()
441482
->fixXmlConfig('hydrator')
442483
->children()
443484
->arrayNode('hydrators')

0 commit comments

Comments
 (0)