Problem

  • When a faulty module has been installed (or when a module is removed from the filesystem) AND the module's entry is removed from the system.module configuration, then
    1. DrupalKernel continuously rebuilds and dumps the service container on every single page request.
    2. DrupalKernel::discoverServiceProviders() triggers a PHP notice.

Cause

  1. DrupalKernel contains a detection for a changed module list already, but the code that tries to compare the list is loading the list of enabled modules through the regular ConfigFactory, which is cached.
  2. DrupalKernel does recognize the difference already and dumps a new service container that no longer contains the remove module.
  3. But due to a configuration cache race-condition, DrupalKernel::$moduleList contains the old/bogus module list.
  4. Subsequent requests are loading the old/bogus module list again, discover a difference, and rebuild + re-dump the container from scratch.

Notes

  • This happens with the rebuild script even.
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

chx’s picture

> if the system.module configuration was manually updated

Manually editing the active store is not supported. It will go away soon.

chx’s picture

I mean, storing the active store in files will go away soon. Meanwhile, human editing those files can break the system in various ways. The sanctioned route is to export, edit and import and then the import validation can stop funny values entering the system.

If it is possible to reproduce this issue without editing the active store, then that's fine.

sun’s picture

The idea of not supporting/allowing to edit the active configuration presents a major conflict with D8's changed paradigm of no longer silently ignoring missing or malformed modules.

As a very trivial example:

  1. Install a new module.
  2. The module happens to be installed and enabled, but causes every request to blow up.
  3. The referred-to functionality (exporting/importing/changing configuration) is no longer available/functional in the first place.

The only possible remedy is to manually remove the module from system.module.yml and run the rebuild script.

The concrete given example is to be disregarded. It is just one of many possible scenarios that one will be facing in real-world D8 development. That is underlined by the fact that the actual scenario I'm currently facing is a different one, too.

As outlined in the issue summary, that procedure works up to the extent that the service container is rebuilt and no longer contains the broken module.

But when DrupalKernel rebuilds the container, it happens to prime its moduleList with a formerly cached list that still contains the broken module.

This stale cache even continues to exist in subsequent requests, which in turn causes DrupalKernel to automatically and silently rebuild the service container on every single request.

As a result, there are multiple flaws in the current DrupalKernel: (1) The container is rebuilt based on outdated cache data, and (2) it is highly concerning that it has a built-in mechanism to silently and automagically rebuild and re-dump the service container in the first place.

This issue solely focuses on (1), and we should create a separate issue to consider removal of (2) since that can only have very unexpected and negative consequences.

(FWIW, it's great to know that a full rebuild and dump only takes a few milliseconds, but when I found out that it happens on every single HTTP request, I was not amused, to say the least.)

chx’s picture

FileSize
3.33 KB

Seems like we have a problem here indeed. I will take this into consideration when rewriting config storage.

Rerolled to initialize config storage only once.

sun’s picture

Status: Needs review » Closed (duplicate)

@tim.plunkett just discovered that this is actually a dupe of #1897468: Kernel rebuilds service container on every request when a module vanishes

Both issues contain some valuable info, and even though this one has a patch, the other one holds much more in-depth considerations on the fundamental problem space itself, so I'm closing this one.