Skip to content

Commit 57a9b43

Browse files
committed
feature #21767 [DI][Router][DX] Invalidate routing cache when container parameters changed (ogizanagi)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DI][Router][DX] Invalidate routing cache when container parameters changed | Q | A | ------------- | --- | Branch? | master | Bug fix? | yes | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #21426 | License | MIT | Doc PR | N/A Supersedes #21443 but only for master. Indeed, this implementation uses a new feature: a `ContainerParametersResource` which compares cached containers parameters (collected at some point, here by the `Router`) with current ones in the container. On the contrary of the previous PR targeting 2.7, this will only invalidate routing cache when parameters actually used in the routes changed and will avoid always rebuilding the routing cache when the container is rebuilt, just to catch the edge case of someone modifying a parameter. Commits ------- fad4d9e2ef [DI][Router][DX] Invalidate routing cache when container parameters changed
2 parents f66afef + 5232f61 commit 57a9b43

File tree

3 files changed

+25
-0
lines changed

3 files changed

+25
-0
lines changed

Resources/config/services.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
<argument /> <!-- resource checkers -->
6161
</service>
6262

63+
<service class="Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker" public="false">
64+
<argument type="service" id="service_container" />
65+
<tag name="config_cache.resource_checker" priority="-980" />
66+
</service>
67+
6368
<service class="Symfony\Component\Config\Resource\SelfCheckingResourceChecker" public="false">
6469
<tag name="config_cache.resource_checker" priority="-990" />
6570
</service>

Routing/Router.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Routing;
1313

14+
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
1415
use Symfony\Component\Routing\Router as BaseRouter;
1516
use Symfony\Component\Routing\RequestContext;
1617
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -27,6 +28,7 @@
2728
class Router extends BaseRouter implements WarmableInterface
2829
{
2930
private $container;
31+
private $collectedParameters = array();
3032

3133
/**
3234
* Constructor.
@@ -53,6 +55,7 @@ public function getRouteCollection()
5355
if (null === $this->collection) {
5456
$this->collection = $this->container->get('routing.loader')->load($this->resource, $this->options['resource_type']);
5557
$this->resolveParameters($this->collection);
58+
$this->collection->addResource(new ContainerParametersResource($this->collectedParameters));
5659
}
5760

5861
return $this->collection;
@@ -153,6 +156,8 @@ private function resolve($value)
153156
$resolved = $container->getParameter($match[1]);
154157

155158
if (is_string($resolved) || is_numeric($resolved)) {
159+
$this->collectedParameters[$match[1]] = $resolved;
160+
156161
return (string) $resolved;
157162
}
158163

Tests/Routing/RouterTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
use PHPUnit\Framework\TestCase;
1515
use Symfony\Bundle\FrameworkBundle\Routing\Router;
16+
use Symfony\Component\DependencyInjection\Config\ContainerParametersResource;
1617
use Symfony\Component\Routing\Route;
1718
use Symfony\Component\Routing\RouteCollection;
1819

@@ -217,6 +218,20 @@ public function testDefaultValuesAsNonStrings($value)
217218
$this->assertSame($value, $route->getDefault('foo'));
218219
}
219220

221+
public function testGetRouteCollectionAddsContainerParametersResource()
222+
{
223+
$routeCollection = $this->getMockBuilder(RouteCollection::class)->getMock();
224+
$routeCollection->method('getIterator')->willReturn(new \ArrayIterator(array(new Route('/%locale%'))));
225+
$routeCollection->expects($this->once())->method('addResource')->with(new ContainerParametersResource(array('locale' => 'en')));
226+
227+
$sc = $this->getServiceContainer($routeCollection);
228+
$sc->setParameter('locale', 'en');
229+
230+
$router = new Router($sc, 'foo');
231+
232+
$router->getRouteCollection();
233+
}
234+
220235
public function getNonStringValues()
221236
{
222237
return array(array(null), array(false), array(true), array(new \stdClass()), array(array('foo', 'bar')), array(array(array())));

0 commit comments

Comments
 (0)