diff --git a/core/lib/Drupal/Core/Routing/RouteBuilder.php b/core/lib/Drupal/Core/Routing/RouteBuilder.php index a4b17e2..c3809db 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilder.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilder.php @@ -121,6 +121,22 @@ public function __construct(MatcherDumperInterface $dumper, LockBackendInterface } /** + * Refreshes the local cache and rechecks if a rebuild is needed. + * + * @return bool + * TRUE if the rebuild is needed, FALSE otherwise. + */ + protected function isRebuildNeededUncached() { + // To absolutely ensure that the router rebuild is required, reset the cache + // in case they were set by another process. + $this->routeBuilderIndicator->resetCache(); + if ($this->routeBuilderIndicator->isRebuildNeeded()) { + return TRUE; + } + return FALSE; + } + + /** * {@inheritdoc} */ public function rebuild() { @@ -133,6 +149,11 @@ public function rebuild() { // We choose to block here since otherwise the routes might not be // available, resulting in a 404. $this->lock->wait('router_rebuild'); + + if ($this->isRebuildNeededUncached()) { + $this->rebuild(); + } + return FALSE; } @@ -215,6 +236,9 @@ public function getCollectionDuringRebuild() { */ public function rebuildIfNeeded() { if ($this->routeBuilderIndicator->isRebuildNeeded()) { + if (!$this->isRebuildNeededUncached()) { + return FALSE; + } return $this->rebuild(); } return FALSE; diff --git a/core/lib/Drupal/Core/Routing/RouteBuilderIndicator.php b/core/lib/Drupal/Core/Routing/RouteBuilderIndicator.php index 5f06120..5cff225 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilderIndicator.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilderIndicator.php @@ -34,6 +34,13 @@ public function __construct(StateInterface $state) { /** * {@inheritdoc} */ + public function resetCache() { + $this->state->resetCache(); + } + + /** + * {@inheritdoc} + */ public function setRebuildNeeded() { $this->state->set(static::REBUILD_NEEDED, TRUE); } diff --git a/core/lib/Drupal/Core/Routing/RouteBuilderIndicatorInterface.php b/core/lib/Drupal/Core/Routing/RouteBuilderIndicatorInterface.php index 68ce5b8..da9f97b 100644 --- a/core/lib/Drupal/Core/Routing/RouteBuilderIndicatorInterface.php +++ b/core/lib/Drupal/Core/Routing/RouteBuilderIndicatorInterface.php @@ -15,6 +15,11 @@ const REBUILD_NEEDED = 'router_rebuild_needed'; /** + * Reset the router builder indicator cache. + */ + public function resetCache(); + + /** * Sets the router to be rebuilt next time the kernel is terminated. * * @see \Drupal\Core\EventSubscriber\RouterRebuildSubscriber::onKernelTerminate() diff --git a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php index b0efe77..5e50083 100644 --- a/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php +++ b/core/tests/Drupal/Tests/Core/Routing/RouteBuilderTest.php @@ -278,9 +278,9 @@ public function testRebuildIfNecessary() { $this->routeBuilderIndicator->expects($this->once()) ->method('setRebuildDone'); - $this->routeBuilderIndicator->expects($this->exactly(2)) + $this->routeBuilderIndicator->expects($this->exactly(3)) ->method('isRebuildNeeded') - ->will($this->onConsecutiveCalls(TRUE, FALSE)); + ->will($this->onConsecutiveCalls(TRUE, TRUE, FALSE)); $this->yamlDiscovery->expects($this->any()) ->method('findAll')