Problem/Motivation
There are situations when it is necessary to determine whether a given instance was retrieved from the container. #2190643: Serializing the container is a very very bad idea, let's prevent it? introduced a public _serviceId property which is assigned to a service whenever it was instantiated. Subsequently it was discovered that this comes with a considerable performance penalty in #2307869: Remove Drupal's Container::get().
In the meantime usage of the public _serviceId expanded (e.g. ConfigImporter::reinjectMe).
Note that ContainerAwareEventDispatcher::removeListener() (both the drupal as well as the symfony) resolves a similar issue by looping through the instantiated subscriber services declared in the container and comparing them to the $listener instance to be removed.
N.b. there have been discussions on pushing DependencySerializationTrait upstream to Symfony, but given its reliance on an undeclared public property and on Drupal::getContainer() this is currently impossible.
Proposed resolution
Stop adding an undeclared public _serviceId to track service names, but instead discover them by searching through the service container. This also makes it possible to remove the Container::get() overrides from the Drupal implementation of the container (performance++).
Implement the reverse service lookup as a service itself. That way it is easy to statically cache the results of previous lookups in a lookup table (e.g. SplObjectStorage) if this is necessary at all.
Remaining tasks
- Write the patch
- Profiling
- Review
User interface changes
None.
API changes
None.
| Comment | File | Size | Author |
|---|---|---|---|
| #31 | 2389193-31.patch | 16.54 KB | Ankit.Gupta |
| #30 | 2389193-30.patch | 18.68 KB | anchal_gupta |
| #26 | interdiff.txt | 649 bytes | andypost |
| #26 | 2389193-26.patch | 18.7 KB | andypost |
| #28 | 2389193-28.patch | 18.68 KB | ravi.shankar |
Comments
Comment #1
znerol commentedComment #2
znerol commentedComment #3
znerol commentedComment #4
znerol commentedComment #6
znerol commentedFix
ConfigImporter::reInjectMe()andLocaleConfigTranslationTest.Comment #8
znerol commentedKinda broken reroll, HEAD changed significantly in the meantime.
Comment #9
znerol commentedRemove remaining occurrences of the
_serviceIdproperty.Comment #13
mpdonadioCan we use debug_zval_dump for some good, old-fashioned reference counting? Or would this be too expensive?
Comment #24
andypostquick re-roll
- added phpunit hunk and core doing it now
- entity storages removed
- I bet tests will fail
btw it looks more like duplicate of #2531564: Fix leaky and brittle container serialization solution
Comment #25
andypostto fix tests and clean-up remaining
_serviceIdusageComment #26
andypostfix cs
Comment #27
geek-merlinI much like the direction this is going. One thing though:
Unlike the current hackish solution, this will not work for "shared=false" services, that get an instance every time the container is asked for them. We may decide to drop DependencySerializationTrait support for non-shared services, but for BC reasons we have to deprecate first and document the new limitaiton.
Comment #28
ravi.shankar commentedAdded reroll of patch #26 on Drupal 9.5.x.
Comment #29
andypostNeeds rework because accepted #2531564: Fix leaky and brittle container serialization solution
Comment #30
anchal_gupta commentedRerolled patch against 9.5x
Comment #31
Ankit.Gupta commentedReroll the patch #28 with Drupal 9.5.x
Comment #33
znerol commentedClosing this, since #3327856: Performance regression introduced by container serialization solution implements the exact same approach.