Skip to content
Snippets Groups Projects
Commit 0bba5d06 authored by Angie Byron's avatar Angie Byron
Browse files

Issue #1798222 by Berdir: Fixed Use lock around router rebuild to avoid race condition.

parent 36669878
No related branches found
No related tags found
2 merge requests!7452Issue #1797438. HTML5 validation is preventing form submit and not fully...,!789Issue #3210310: Adjust Database API to remove deprecated Drupal 9 code in Drupal 10
...@@ -67,7 +67,8 @@ public function build(ContainerBuilder $container) { ...@@ -67,7 +67,8 @@ public function build(ContainerBuilder $container) {
$container->register('router.dumper', 'Drupal\Core\Routing\MatcherDumper') $container->register('router.dumper', 'Drupal\Core\Routing\MatcherDumper')
->addArgument(new Reference('database')); ->addArgument(new Reference('database'));
$container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder') $container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder')
->addArgument(new Reference('router.dumper')); ->addArgument(new Reference('router.dumper'))
->addArgument(new Reference('lock'));
$container->register('matcher', 'Drupal\Core\Routing\ChainMatcher'); $container->register('matcher', 'Drupal\Core\Routing\ChainMatcher');
$container->register('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher') $container->register('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher')
......
...@@ -7,8 +7,7 @@ ...@@ -7,8 +7,7 @@
namespace Drupal\Core\Routing; namespace Drupal\Core\Routing;
use Symfony\Component\Routing\RouteCompilerInterface; use Drupal\Core\Lock\LockBackendInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface; use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
/** /**
...@@ -26,20 +25,38 @@ class RouteBuilder { ...@@ -26,20 +25,38 @@ class RouteBuilder {
*/ */
protected $dumper; protected $dumper;
/**
* The used lock backend instance.
*
* @var \Drupal\Core\Lock\LockBackendInterface $lock
*/
protected $lock;
/** /**
* Construcs the RouteBuilder using the passed MatcherDumperInterface. * Construcs the RouteBuilder using the passed MatcherDumperInterface.
* *
* @param Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface $dumper * @param \Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface $dumper
* The matcher dumper used to store the route information. * The matcher dumper used to store the route information.
* @param \Drupal\Core\Lock\LockBackendInterface $lock
* The lock backend.
*/ */
public function __construct(MatcherDumperInterface $dumper) { public function __construct(MatcherDumperInterface $dumper, LockBackendInterface $lock) {
$this->dumper = $dumper; $this->dumper = $dumper;
$this->lock = $lock;
} }
/** /**
* Rebuilds the route info and dumps to dumper. * Rebuilds the route info and dumps to dumper.
*/ */
public function rebuild() { public function rebuild() {
if (!$this->lock->acquire('router_rebuild')) {
// Wait for another request that is already doing this work.
// We choose to block here since otherwise the routes might not be
// available, resulting in a 404.
$this->lock->wait('router_rebuild');
return;
}
// We need to manually call each module so that we can know which module // We need to manually call each module so that we can know which module
// a given item came from. // a given item came from.
...@@ -49,6 +66,7 @@ public function rebuild() { ...@@ -49,6 +66,7 @@ public function rebuild() {
$this->dumper->addRoutes($routes); $this->dumper->addRoutes($routes);
$this->dumper->dump(array('route_set' => $module)); $this->dumper->dump(array('route_set' => $module));
} }
$this->lock->release('router_rebuild');
} }
} }
...@@ -452,10 +452,12 @@ function update_check_requirements($skip_warnings = FALSE) { ...@@ -452,10 +452,12 @@ function update_check_requirements($skip_warnings = FALSE) {
->setFactoryClass('Drupal\Core\Database\Database') ->setFactoryClass('Drupal\Core\Database\Database')
->setFactoryMethod('getConnection') ->setFactoryMethod('getConnection')
->addArgument('default'); ->addArgument('default');
$container->register('lock', 'Drupal\Core\Lock\DatabaseLockBackend');
$container->register('router.dumper', '\Drupal\Core\Routing\MatcherDumper') $container->register('router.dumper', '\Drupal\Core\Routing\MatcherDumper')
->addArgument(new Reference('database')); ->addArgument(new Reference('database'));
$container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder') $container->register('router.builder', 'Drupal\Core\Routing\RouteBuilder')
->addArgument(new Reference('router.dumper')); ->addArgument(new Reference('router.dumper'))
->addArgument(new Reference('lock'));
// Turn error reporting back on. From now on, only fatal errors (which are // Turn error reporting back on. From now on, only fatal errors (which are
// not passed through the error handler) will cause a message to be printed. // not passed through the error handler) will cause a message to be printed.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment