Commit 0bba5d06 authored by webchick's avatar webchick

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

parent 36669878
......@@ -67,7 +67,8 @@ public function build(ContainerBuilder $container) {
$container->register('router.dumper', 'Drupal\Core\Routing\MatcherDumper')
->addArgument(new Reference('database'));
$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('legacy_url_matcher', 'Drupal\Core\LegacyUrlMatcher')
......
......@@ -7,8 +7,7 @@
namespace Drupal\Core\Routing;
use Symfony\Component\Routing\RouteCompilerInterface;
use Symfony\Component\Routing\Route;
use Drupal\Core\Lock\LockBackendInterface;
use Symfony\Component\Routing\Matcher\Dumper\MatcherDumperInterface;
/**
......@@ -26,20 +25,38 @@ class RouteBuilder {
*/
protected $dumper;
/**
* The used lock backend instance.
*
* @var \Drupal\Core\Lock\LockBackendInterface $lock
*/
protected $lock;
/**
* 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.
* @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->lock = $lock;
}
/**
* Rebuilds the route info and dumps to dumper.
*/
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
// a given item came from.
......@@ -49,6 +66,7 @@ public function rebuild() {
$this->dumper->addRoutes($routes);
$this->dumper->dump(array('route_set' => $module));
}
$this->lock->release('router_rebuild');
}
}
......@@ -452,10 +452,12 @@ function update_check_requirements($skip_warnings = FALSE) {
->setFactoryClass('Drupal\Core\Database\Database')
->setFactoryMethod('getConnection')
->addArgument('default');
$container->register('lock', 'Drupal\Core\Lock\DatabaseLockBackend');
$container->register('router.dumper', '\Drupal\Core\Routing\MatcherDumper')
->addArgument(new Reference('database'));
$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
// not passed through the error handler) will cause a message to be printed.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment