RecipeRunner::processInstall() installs modules one by one

Created on 7 January 2025, 13 days ago

Problem/Motivation

Testing installing a module via project browser, I noticed 10 separate calls to ModuleInstaller::install(). The project browser request to install the recipe required a total of over 160mb of memory and took 14 seconds.

This is from RecipeRunner::processInstall() which installs modules one by one.

It means it can't take advantage of πŸ“Œ Add the ability to install multiple modules and only do a single container rebuild to ModuleInstaller Active , at all, which by itself will be a significant improvement from 11.2 onwards, but ModuleInstaller::install() in 11.1 already has some optimisations when multiple modules are installed at once.

Steps to reproduce

Proposed resolution

Remaining tasks

User interface changes

Introduced terminology

API changes

Data model changes

Release notes snippet

πŸ“Œ Task
Status

Active

Version

11.0 πŸ”₯

Component

recipe system

Created by

πŸ‡¬πŸ‡§United Kingdom catch

Live updates comments and jobs are added and updated live.
  • Performance

    It affects performance. It is often combined with the Needs profiling tag.

Sign in to follow issues

Comments & Activities

  • Issue created by @catch
  • πŸ‡¬πŸ‡§United Kingdom catch
  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    Note we need to think about \Drupal\Core\Recipe\RecipeRunner::toBatchOperationsInstall() too

    It's likely this change will result in quite a bit of refactoring.

  • πŸ‡¬πŸ‡§United Kingdom alexpott πŸ‡ͺπŸ‡ΊπŸŒ

    The tricky bit here will be

        // Disable configuration entity install but use the config directory from
        // the module.
        \Drupal::service('config.installer')->setSyncing(TRUE);
        $default_install_path = \Drupal::service('extension.list.module')->get($module)->getPath() . '/' . InstallStorage::CONFIG_INSTALL_DIRECTORY;
        // Allow the recipe to override simple configuration from the module.
        $storage = new RecipeOverrideConfigStorage(
          $recipeConfigStorage,
          new FileStorage($default_install_path, StorageInterface::DEFAULT_COLLECTION)
        );
    

    @phenaproxima suggested wrapping all the config from all the modules together. This might work because modules cannot have conflicting config - we have the PreExistingConfiguration exception that handles that. I'm concerned that it might not work because that when you install the first module it'd discover all the configuration from the modules that are yet to be installed. Not sure how that's going to work out.

Production build 0.71.5 2024