Problem/Motivation
Although Drupal depends on symfony/dependency-injection, it barely uses it. Drupal maintains own container implementation. Besides a dependency container written from scratch it also contains a custom dumper for it. See #2497243: Replace Symfony container with a Drupal one, stored in cache for historical reference.
This container implementation is compatible with the default Symfony
dependency injection container and similar to the Symfony ContainerBuilder
class, but optimized for speed.
Even though the container documentation claims to optimize for speed, I think it actually has worse performance than the native Symfony container. However, I don't have any benchmarks yet.
The are two primary performance issues with the current implementation.
- The container is cached in database, which implies opening DB connection and fetching rather big piece of data (up to 1 MB). Symfony offers a PhpDumper that can be used to store container in Opcache.
- Lots of
unserialize()calls. Each service definition is serialized individually and the entire container is serialized as well.
Besides performance, there are other issues:
- Maintenance cost. We have to support self-made DI implementation.
- Features from Symfony DI are not available by default. See #3021900: Bring new features from Symfony 3/4/5/6/7 into our container.
Proposed resolution
Replace Drupal container with a Symfony one.
Comments
Comment #2
chi commentedOpening DB connection is rather expensive operation, especially in PostgreSQL. Even if the cache is managed through in memory backend (Redis/Memcache) Drupal will open DB connection as bootstrap container depends on Database service.
Comment #3
catchThe Symfony container is written to a PHP file, unless something has changed.
We can't require write permissions to a PHP file in production.
Modules being installed/uninstalled and affecting the container means we also can't require the container is compiled at build time.
These are the two reasons we moved to keeping the container in the database in the first place and they both continue to be valid as far as I know. The original decision to use Symfony's container ignored both of these constraints and we've been dealing with that since.
Comment #4
chi commentedFor Twig files it was resolved in #2544932: Twig should not rely on loading php from shared file system. Can it be done same way for containers?
Anyway DB based container cache may still exist and used as fallback for sites that rebuild containers in non CLI SAPI. The point is to use more efficient solution by default.