Problem/Motivation

\Drupal\Core\Extension\ExtensionDiscovery is not a service. It is always instantiated in hard-coded ways, and stores all discovered extensions in a static class property. Once extensions in a particular extension collection directory (such as ./modules or ./modules) are discovered, the statically cached information can and will not be updated until the next request.

As a consequence of this behavior, enabling a module and subsequently using it in the same request is impossible, because enabling the module requires a bootstrap, which requires extensions to be discovered. Any extension that is enabled after bootstrap, will not be available until the next request.

This has caused minor problems in the past, even in Drupal 7, but currently this is a major roadblock for Console.

Proposed resolution

Convert the extension discovery into a service and add a method to reset scanned dependencies, forcing the class to scan again upon the next request for the list of available extensions.

This will also allow us to inject the extension discovery into the module and theme installers, and trigger a rescan when a new extension is installed. This can be done in a follow-up.

Remaining tasks

Convert ExtensionDiscovery to a service and add a method to reset the static cache.

User interface changes

None.

API changes

Code instantiating ExtensionDiscovery must be converted to use the service instead, either through injection or service location.

Comments

Xano’s picture

Title: ExtensionDiscovery » Convert ExtensionDiscovery to a service
Issue tags: -Convert ExtensionDiscovery to a service
dawehner’s picture

jibran’s picture

I agree with @dawehner.

jibran’s picture

@Xano would you like to make this argument in #2208429: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList so that we can change that to bug report and convince core committers?

jonhattan’s picture

We have the very same problem in Drush - https://github.com/drush-ops/drush/issues/5

gapple’s picture

#2156401: Write install_profile value to configuration and only to settings.php if it is writeable adds a static reset method to ExtensionDiscovery for testing purposes. (Which unfortunately conflicts with DrupalConsole's non-static declaration in a subclass).

dawehner’s picture

One thing you have to keep in mind is that at the moment the ExtensionDiscovery is by design not really swappable, because its needed to build the actual container, so wapping it out on the container level would work different than expected.

Mile23’s picture

I like this idea, but with some caveats mentioned here: #2186491-17: [meta] D8 Extension System: Discovery/Listing/Info

I'm coming at this because I want to be able to test ExtensionDiscovery: #2605654: Modify Drupal\Core\Extension\ExtensionDiscovery to allow for scanning multiple file systems, enabling vfsStream testing

Basically we need to be able to use ExtensionDiscovery without a container or any dependencies, in order to do super-quick test discovery.

dawehner’s picture

Basically we need to be able to use ExtensionDiscovery without a container or any dependencies, in order to do super-quick test discovery.

Well, we even need it in order to be able to not have circular dependency problems.

So to be clear, with #2208429: Extension System, Part III: ExtensionList, ModuleExtensionList and ProfileExtensionList you'll no longer use the ExtensionDiscovery in any of your code.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

donquixote’s picture

It is a noble effort trying to fix existing components.
But maybe it is easier to write new components that work as promised, and use them as services or whichever way we like, while leaving the old ones in place. Usages of the old components would slowly pick up on the new ones.

The ExtensionDiscovery has some problems which can be fixed. One of them is adding the additional key [$this->root] to the static cache, as in #2605654-48: Modify Drupal\Core\Extension\ExtensionDiscovery to allow for scanning multiple file systems, enabling vfsStream testing.
But beyond this, we probably need to leave some of the crappy behavior in place for existing components that are already depending on it. One of the flaws is the existence of a setProfileDirectories() method, which makes this object mutable and thus not suitable as a service.

If a depending component already needs to be modified (to use a service instead of calling a constructor), it can as well use a different tool that does the job more reliably.

I experimented, and came up with an architecture where a lot of things can be swapped out for testing, and individual components can be tested individually.
#2724231: Replacement for ExtensionDiscovery, following SOLID principles

I think this is the direction to go. Not necessarily 1:1 my demo code, but the direction.

Xano’s picture

It's clear to me that we cannot make this a service. Could we make it a low-level setting instead? That way we allow experimental discovery methods while keeping this out of the service container.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.4.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.5.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

Bug reports should be targeted against the 8.6.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.6.x-dev » 8.8.x-dev

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

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

Drupal 8 is end-of-life as of November 17, 2021. There will not be further changes made to Drupal 8. Bugfixes are now made to the 9.3.x and higher branches only. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.2.x-dev » 9.3.x-dev
catch’s picture

Status: Active » Closed (duplicate)
Mile23’s picture