Problem
-
use Drupal\Core\Config\InstallStorage; /** * Defines the file storage controller for metadata files. */ class SchemaStorage extends InstallStorage {
Details
-
The InstallStorage was explicitly designed to operate in the initial installer environment, in which the base system is not operable yet — it therefore performs plenty of filesystem scans (as opposed to relying on readily available application state information) and it also ignores the installation status of discovered extensions.
-
The InstallStorage was never intended to be used outside of the installer. In fact, as also clarified in #2155701: Installer starts with fatal error/exception "table 'semaphore' not found" if settings.php contains $databases already, the installer's minimal service container including InstallStorage is only used in the very first 2-3 installer screens until the base system has been set up and verified. As soon as System module and User module are installed, the installer uses a regular DrupalKernel with regular runtime services. Not even the installer uses Config\InstallStorage from that point anymore, because application state and extension information is readily available.
-
The use of InstallStorage by the SchemaStorage most likely causes a major slowdown in performance; at minimum in the installer (and consequently tests).
| Comment | File | Size | Author |
|---|---|---|---|
| #11 | 2166703.11.patch | 23.74 KB | alexpott |
| #11 | 9-11-interdiff.txt | 1.19 KB | alexpott |
| #9 | 7-9-interdiff.txt | 8.14 KB | alexpott |
| #9 | 2166703.9.patch | 23.56 KB | alexpott |
| #7 | 2166703.7.patch | 17.02 KB | alexpott |
Comments
Comment #1
alexpottThe patch attached changes the
SchemaStorageto extend fromExtensionInstallStorageinstead which whilst still based onInstallStorageis limited to only enabled extensions.This should result in quicker
DrupalUnitTestBasetests and in general a smaller cache entry for schema definitions.Comment #3
sunThe test failures are triggering two questions for me:
Comment #4
alexpott1. This clears the cache during the module install - schema's should never change during regular runtime. The ExtensionInstallStorage is only ever used in the
ConfigInstallerand is not cached anywhere.2. You're correct migrate_drupal tests are not enabling the module - I consider this a bug.
Comment #5
alexpottMinor fix to EOF
Comment #6
berdirWe do have that stupid standard docblock for $modules...
I guess the system.module trick is for DUBT tests that don't enable system, or are there other reasons?
Confirmed that this does work and the time that DUBT tests spend for this goes down, they still have to parse the stuff in system.module, obviously.
Comment #7
alexpottThe system module trick is because we write config before we truly have the system module enabled - see drupal_install_system() and yes also to ensure in DUBT that we have the minimum of config schema available.
There are many examples in core where this doc block is missing but here you go :)
Comment #8
sunI'm still concerned about two discrete things:
1. The config.storage.schema service is not persisted, so every kernel/container rebuild will actually empty out the $folders property, since the whole class instance is replaced with a new one?
ModuleHandler::install() + ::uninstall() are calling DrupalKernel::updateModules(), which rebuilds the container.
→ Manually clearing the cache seems to be superfluous?
→ In order to persist $folders across rebuilds, the property either has to be static, or the config.storage.schema service would have to be tagged with 'persist'?
2. This may cover the module installation case, but the case of uninstalling a module is not covered?
→ Config schema definitions of a previously installed module are leaking into the next rebuild?
3. Performance-wise, it would be a much better idea to specifically trigger a refresh of config schema information for a particular extension, instead of rescanning and rebuilding everything?
→ Shouldn't we replace this with explicit calls from ModuleHandler::install() + ::uninstall()?
Like parent::getAllFolders(), this condition should use !isset() rather than empty() for clarity and consistency, and to prevent it from being executed in unwanted situations.
I'm not sure I see the relation to DUTB, but if this specifically refers to the following lines in drupal_install_system():
...then I wonder:
1. Can we omit that enforced inclusion by simply swapping the order of setModuleList() vs. config() in drupal_install_system()?
2. In case (1) does not work and we still have to keep this, then we should clarify this comment to clearly state why it is needed, including @see pointers + a @todo to resolve this circular dependency ASAP.
Comment #9
alexpottModuleHandler has to depend on ConfigInstaller
ConfigInstaller has to depend on ConfigFactory and TypedConfigManager
ConfigFactory has to depend on TypedConfigManager
But doing this does not get round the fact that in order to write config with need the schema and the module list is held in config.
Comment #10
sunThanks!
Overall, while the config schema code still looks very slow, fragile, and confusing to me, I think that this is certainly a step in the right direction.
Can we create a major follow-up issue to move the base configuration schema definitions from system.module into the Config\Schema component itself?
Let's simply add a /core/lib/Drupal/Core/Config/Schema/schema.yml file and force-include it manually, so we can get rid of the unnecessary dependency on system.module.
Comment #11
alexpottLets get the core data types issue fixed here :)
Comment #12
sunEven better!
I secretly hoped that this would allow us to remove/revert some more workarounds, but ok...
Comment #13
catchCommitted/pushed to 8.x, thanks!