Problem/Motivation
There is a design pattern that derivers statically cache the resulting derivatives (e.g. \Drupal\Component\Plugin\Derivative\DeriverBase::$derivatives
). This can result in out of date derivatives data to be rebuild and cached, despite other things correctly calling clearing the plugin manager caches. The example we have in the Contacts module is:
- Install Contacts module
- Some stuff happens which involves getting definitions from the block manager (possibly importing page manager pages?). This primes the static caches.
- Facet config entities are imported. Facets (with patch in #2880411-6: Facets added via config don't clear the block cache) clear the block plugin cached definitions expecting those blocks now to be found next time the definitions are rebuild.
- Some stuff happens which gets the definitions from the block manager (possible other page manager pages?). This results in using the existing static cache and returning the old, now stale, derivatives.
- Because the cache has been rebuilt, future requests use this already stale version of the cache.
This can be worked around in contrib by clearing the plugin.manager.block
service from the container in addition to clearing the cached definitions.
Proposed resolution
Not sure what should actually be done, initial thoughts on possible solutions:
- Stop statically caching... If we attempt to get derivatives twice in a request that will be because the cache has been cleared and we need to get them fresh. I don't know if this is just a documentation/change record and then fix in contrib or if there are BC issues (e.g. is
\Drupal\Component\Plugin\Derivative\DeriverBase
public API or internal)... - Don't store the derivers as part of
\Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator
, which effectively renders the static caches irrelevant. This could have a performance overhead (though again a questionable benefit in the first place?), but fix all contrib even if it continues using the static pattern. Probably worth doing above in addition... - Make
\Drupal\Core\Plugin\DefaultPluginManager::clearCachedDefinitions
clear itself off the container or clear the cached derivers...
Remaining tasks
Decide how to solve this...
User interface changes
None.
API changes
Depends on the decision...
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#38 | interdiff-32-1.txt | 1.06 KB | zeeshan_khan |
#38 | 2880682-32.patch | 1.79 KB | zeeshan_khan |
#31 | interdiff_30-31.txt | 459 bytes | immaculatexavier |
#31 | 2880682-31.patch | 1.78 KB | immaculatexavier |
| |||
#30 | interdiff_26-30.txt | 503 bytes | immaculatexavier |
Issue fork drupal-2880682
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
tim.plunkettPossible duplicate of #2860346: Reset plugin discovery when a module/theme is installed?
Comment #3
andrewbelcher CreditAttribution: andrewbelcher at FreelyGive commentedPossibly, I think they may both describe a similar problem, but in this case the issue isn't the module install, it's config installation, so simply resetting at module install won't catch this scenario.
Comment #4
tim.plunkettI agree. But I think this will be blocked on that issue, as it adds the necessary
$this->discovery = NULL;
change.Comment #7
larowlanAnother case #2902281: Configuration import fails
The issue there is \Drupal\Component\Plugin\Discovery\DerivativeDiscoveryDecorator::getDeriver has a static cache
Comment #8
larowlanthis at least unblocks my project, no tests etc
sticking here for composer patches sake
Comment #9
tim.plunkettCan also be {@inheritdoc}
This is a weird method. But AFAICS this unset should be wrapped in a
if (!$use_caches) {
Comment #10
larowlanwe should trigger a deprecated error in the else section, so we can remove the instanceof check in d9 and force discoveryinterface to extend the cached version
agree on all points from @tim.plunkett review
Comment #12
larowlanreroll for 8.6
Comment #13
rigoucr CreditAttribution: rigoucr as a volunteer and at Manatí commentedI think that @larowlan forgot about to change this issue status from needs work to needs review when sent the re-roll of the patch
Changing issue status to needs new
Comment #14
rigoucr CreditAttribution: rigoucr as a volunteer and at Manatí commentedI was having this issue: https://www.drupal.org/project/search_api_autocomplete/issues/2902281#co... during the installation of my site and I solved it applying the patch in comment #12. It works for me.
Comment #15
alexpottWe're adding a method with no usages - that tends to get us into trouble.
There's also no test coverage.
I suspect that #3001284: Allow plugin derivers to specify cache tags tags for their definitions might also help with this.
Comment #16
mpp CreditAttribution: mpp at District09 for District09 commentedhttps://www.drupal.org/project/search_api_autocomplete/issues/2902281
I'm adding the issue mentioned by @rigoucr. The search_api_autocomplete SearchPluginDeriverBase has a static cache $derivatives that breaks our config import:
On the first run of ViewsDeriver::getDerivativeDefinitions the static cache is created (for search_api_autocomplete.search.contacts) but for the second one (search_api_autocomplete.search.sg_search) it uses the static cache that doesn't know about the second view (views.view.sg_search).
The static cache isn't updated when a another view is added (either by module installation or config sync).
Comment #23
larowlanComment #24
karishmaamin CreditAttribution: karishmaamin at Specbee commentedRe-rolled patch against 9.4.x. Please review
Comment #25
larowlanBack to needs work for #15
Comment #26
immaculatexavier CreditAttribution: immaculatexavier as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedRerolled against #15
Comment #27
immaculatexavier CreditAttribution: immaculatexavier as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedRerolled against #15
Comment #28
borisson_Back to NW, #15 needs to be resolved (tests).
The method added (useCaches) was not implemented in the last patch (#26), which is why it fails
Comment #29
borisson_Comment #30
immaculatexavier CreditAttribution: immaculatexavier as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedAddressed fix against #28 with interdiff
Comment #31
immaculatexavier CreditAttribution: immaculatexavier as a volunteer and at Srijan | A Material+ Company for Drupal India Association commentedAddressed fix against #30 with interdiff
Comment #32
borisson_In #15 @alexpott said this, but this is a method that is implemented because the interface needs it. That's also why #26 failed.
So all we need now is for the tests to be added, they can be similar to the tests that were needed to test the CachedDiscoveryInterface in other places I think. Or is it just that we want to test that the cached discovery is implemented? I don't think we need to actually test the caching behavior again here?
Comment #35
smustgrave CreditAttribution: smustgrave at Mobomo commentedThis issue is being reviewed by the kind folks in Slack, #needs-review-queue-initiative. We are working to keep the size of Needs Review queue [2700+ issues] to around 400 (1 month or less), following Review a patch or merge request as a guide.
Moving to NW for the test cases.
Also IS has several proposed solutions. Can we highlight which was chosen please
Thanks
Comment #38
zeeshan_khan CreditAttribution: zeeshan_khan as a volunteer commentedRerolled patch for 10.1.x, I needed this for very important project.