Commit e0d57869 authored by catch's avatar catch
Browse files

Issue #3086307 by alexpott, shaal, tstoeckler, mglaman, Berdir, andypost,...

Issue #3086307 by alexpott, shaal, tstoeckler, mglaman, Berdir, andypost, chr.fritsch, borisson_: Improve installer performance by ~20% by rebuilding the router after the entire installation is complete rather than after each module
parent 4cb745d6
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -619,9 +619,8 @@ function drupal_install_system($install_state) {
    ->set('profile', $install_state['parameters']['profile'])
    ->save();

  // Install System module and rebuild the newly available routes.
  // Install System module.
  $kernel->getContainer()->get('module_installer')->install(['system'], FALSE);
  \Drupal::service('router.builder')->rebuild();

  // Ensure default language is saved.
  if (isset($install_state['parameters']['langcode'])) {
+26 −21
Original line number Diff line number Diff line
@@ -7,6 +7,7 @@
use Drupal\Core\DrupalKernelInterface;
use Drupal\Core\Entity\EntityStorageException;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\Core\Installer\InstallerKernel;
use Drupal\Core\Serialization\Yaml;

/**
@@ -209,6 +210,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
        $this->moduleHandler->load($module);
        module_load_install($module);

        if (!InstallerKernel::installationAttempted()) {
          // Replace the route provider service with a version that will rebuild
          // if routes used during installation. This ensures that a module's
          // routes are available during installation. This has to occur before
@@ -219,6 +221,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
          // have replaced it before.
          \Drupal::getContainer()->set('router.route_provider.old', \Drupal::service('router.route_provider'));
          \Drupal::getContainer()->set('router.route_provider', \Drupal::service('router.route_provider.lazy_builder'));
        }

        // Allow modules to react prior to the installation of a module.
        $this->moduleHandler->invokeAll('module_preinstall', [$module]);
@@ -331,6 +334,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {

    // If any modules were newly installed, invoke hook_modules_installed().
    if (!empty($modules_installed)) {
      if (!InstallerKernel::installationAttempted()) {
        // If the container was rebuilt during hook_install() it might not have
        // the 'router.route_provider.old' service.
        if (\Drupal::hasService('router.route_provider.old')) {
@@ -343,6 +347,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
          // page was sent already.
          \Drupal::service('router.builder')->rebuild();
        }
      }

      $this->moduleHandler->invokeAll('modules_installed', [$modules_installed, $sync_status]);
    }
+26 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\Core\Installer;

use Drupal\Core\Routing\RouteProviderLazyBuilder;
use Symfony\Component\Routing\Route;

/**
 * A Route Provider front-end for use during the installer.
 */
class InstallerRouteProviderLazyBuilder extends RouteProviderLazyBuilder {

  /**
   * {@inheritdoc}
   */
  public function getRouteByName($name) {
    if ($name === '<none>' || $name === '<front>') {
      // During the installer template_preprocess_page() uses the routing system
      // to determine the front page. At this point building the router for this
      // is unnecessary work.
      return new Route('/');
    }
    return parent::getRouteByName($name);
  }

}
+12 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderInterface;
use Drupal\Core\Lock\NullLockBackend;
use Symfony\Component\DependencyInjection\Reference;

/**
 * Service provider for the installer environment.
@@ -49,6 +50,17 @@ public function register(ContainerBuilder $container) {
    $container->getDefinition('extension.list.module')->setClass(InstallerModuleExtensionList::class);
    $container->getDefinition('extension.list.theme')->setClass(InstallerThemeExtensionList::class);
    $container->getDefinition('extension.list.theme_engine')->setClass(InstallerThemeEngineExtensionList::class);

    // Don't register the lazy route provider in the super early installer.
    if (get_called_class() === NormalInstallerServiceProvider::class) {
      $lazy_route_provider = $container->register('router.route_provider.installer');
      $lazy_route_provider
        ->setClass(InstallerRouteProviderLazyBuilder::class)
        ->setDecoratedService('router.route_provider')
        ->addArgument(new Reference('router.route_provider.installer.inner'))
        ->addArgument(new Reference('router.builder'))
        ->addTag('event_subscriber');
    }
  }

}
+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,6 @@ public function __construct(RouteProviderInterface $route_provider, RouteBuilder
  protected function getRouteProvider() {
    if (!$this->rebuilt && !$this->rebuilding) {
      $this->routeBuilder->rebuild();
      $this->rebuilt = TRUE;
    }
    return $this->routeProvider;
  }
@@ -190,6 +189,7 @@ public function routerRebuilding() {
   */
  public function routerRebuildFinished() {
    $this->rebuilding = FALSE;
    $this->rebuilt = TRUE;
  }

}
Loading