Problem/Motivation

There is a common best practice in the community to override cache backend with Redis without having the module enabled. It took time while the current best practice was developed because replacing the default cache backend and container backend is not that simple (f.e. while the site is installed it cannot be done).

The problem is the current approach is not a bulletproof solution either. If you have a service provider which calls a cached service you get an error like:

In ContainerBuilder.php line 1060:
  You have requested a non-existent service "cache.backend.redis".  

I believe this issue could be only fixed by changing things in the core because currently, it seems there is no actual way for contrib modules to replace the default cache backends, or does and don'ts are not documented clearly.

Steps to reproduce

1. Add a service provider to a module that tries to access a cached service, like a module handler.

final class MYMODULEServiceProvider implements ServiceProviderInterface {

  /**
   * {@inheritdoc}
   */
  public function register(ContainerBuilder $container): void {
    /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
    $module_handler = $container->get('module_handler');
    try {
      $this_module_relative_path = $module_handler->getModule('MYMODULE')->getPath();
    }
    catch (\Exception $e) {
      throw new LogicException('Unable to identify installation path of this module.');
    }
  }

}

2. Enable the module.
3. Install the Redis module with Composer but do not enable it.
4. Add the above-linked configuration to settings.php which replaces the default cache backend and container cache with Redis.
5 Run drush cr and you should see the error above.

Technical analysis

So what is happening here?

1. $settings['container_yamls'] registers Redis services among the site-level service YAMLs
2. $settings['bootstrap_container_definition'] ensures that Redis is used in the "bootstrap_container". This feature is undocumented.
3. Service definitions from the "bootstrap_container" are not being used when the site container is being built here.
4. When the container is being built then first app-level services gets registered (everything that is core and enabled core/contrib modules). Site level services from YAMLs (like sites/default/services.yml) and service providers only get registestered after because they are considered as overrides.

and BUMMM!!!!

1. Redis module is not enabled there it is not registered as an app-level service.
2. Module handler (or any other cached app-level service) depends on Redis cache backend but the cached backend is not registered because
3.

$settings['container_yamls'] registers Redis services among the site-level service yamls

Proposed resolution

Remaining tasks

User interface changes

API changes

Data model changes

Release notes snippet

Comments

mxr576 created an issue. See original summary.

mxr576’s picture

Assigned: Unassigned » mxr576

TODO Add possible resolution ideas later.

mxr576’s picture

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

damienmckenna’s picture

I've noticed a similar problem in #3272587 where changes made to development.services.yml don't override changes made to services.yml.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.