Allow modules to change the container cache key

Created on 1 June 2023, over 1 year ago
Updated 3 June 2023, over 1 year ago

Problem/Motivation

Normally, to rebuild the Drupal service container, one simply needs to run drush cr, or request an equivalent operation from the UI.
However, this does not work if definitions for low-level services such as 'module_handler' have changed.
See πŸ› Changes to service definitions can cause fatal errors until services cache is cleared Active and πŸ“Œ Refactoring hux services breaks container rebuild Closed: cannot reproduce .

One solution to this problem is to change the $settings['deployment_identifier'] in sites/*/settings.php.
See #3153335: Document $settings['deployment_identifier'] (and that it fixes moved class autoloader caching) β†’
(alternatively there is also core/rebuild.php, but it requires some extra steps to use during a deployment.)

In fact, the DrupalKernel->getContainerCacheKey() produces an invariant that, when changed, causes an early container rebuild.
The 'deployment_identifier' is just one part of this invariant.

  protected function getContainerCacheKey() {
    $parts = ['service_container', $this->environment, \Drupal::VERSION, Settings::get('deployment_identifier'), PHP_OS, serialize(Settings::get('container_yamls'))];
    return implode(':', $parts);
  }

However, there is currently no clean way for modules (contrib or custom) to modify this value.
A contrib module would have to ask the website developer to add something to their settings.php.

Steps to reproduce

Here are some steps you could try in an existing Drupal development website:

  1. Rename the ModuleHandler class in core, and update core.services.yml accordingly.
    Or alternatively, install hux and change the service definition for the HuxModuleHandler.
    Or any other low-level service that is needed pre-bootstrap.
  2. Attempt to open the website, or attempt to run drush cache:rebuild (drush cr).

Expected: Container gets rebuilt eventually on drush cr.
Actual: You get errors like "class not found" or "invalid arguments", because services are created based on the old cached container definition.

This just shows the basic problem.

Proposed resolution

Add a value in DrupalKernel->getContainerCacheKey() that can be influenced by modules (contrib or custom), without the need for a website developer to do anything in settings.php.

How exactly this should work can be discussed.

Some ideas:

  • Let composer generate a value on composer install, which can be easily read by Drupal in bootstrap.
    E.g. we don't want to parse a complete composer.lock file, instead we want a very small file which only contains one value to be compared.
    But I am not sure how far we would get with this composer route.
  • Allow modules to register a static method or a constant that will be evaluated from DrupalKernel->getContainerCacheKey().
  • Provide a static method in Drupal core that can be called from a *.modules file, or from a file that is included through composer.

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

✨ Feature request
Status

Active

Version

11.0 πŸ”₯

Component
BaseΒ  β†’

Last updated 3 days ago

Created by

πŸ‡©πŸ‡ͺGermany donquixote

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Production build 0.71.5 2024