#2202185: Statically cache Role entities to speed up (User|UserSession)::hasPermission() wants to enable entity static caching for user roles. #1885830: Enable static caching for config entities wants to do it by default for all config entities. Both issues have run into the problem that the cache is broken as per this issue's title, since it is not yet used by any config entities in core.
Regardless of which, if any, core config entities we want to statically cache, it needs to be possible for contrib to enable static caching for their own entities, or turn it on for core ones.
Therefore, this issue is to add a test that is independent of core usages and fix the found bugs.
Comment | File | Size | Author |
---|---|---|---|
#16 | interdiff.txt | 4.79 KB | effulgentsia |
#16 | 2303881.16.patch | 11.78 KB | effulgentsia |
#11 | 2303881.11.patch | 11.67 KB | alexpott |
#11 | 2-11-interdiff.txt | 2.94 KB | alexpott |
#2 | interdiff.txt | 4.56 KB | effulgentsia |
Comments
Comment #1
effulgentsia CreditAttribution: effulgentsia commentedHere's the test to demonstrate the failures.
Comment #2
effulgentsia CreditAttribution: effulgentsia commentedAnd here's the fix.
Comment #3
BerdirThis does change the structure of $this->entities, which was recently improved to document what it contains. So it would be different for this. Not sure how to properly document that.
Comment #5
effulgentsia CreditAttribution: effulgentsia commentedRe #3: #2 contains:
Do you think additional docs are needed somewhere?
Comment #6
BerdirOuch, no idea why I missed that, yes that looks great. You're just too good at this, only a bit thinking out loud below, no real feedback :)
Would also appreciate your thoughts in #1885830: Enable static caching for config entities in regards to enabling it by default vs. only doing it for config entities where we know it's worth it, like roles.
Apparently it's not a problem that we're moving when exactly the caches are cleared, and there's almost nothing after that, so that seems fine, even logical to do it after the translation hooks were called too.
That said, there is #1729812: Separate storage operations from reactions, not exactly sure what this would mean. I guess it would still be fine as the hooks already happen in the parent and the current implementation needs to override save() to be able to have them inside the transaction.
It worked pretty well to use unit tests for cache hit/miss testing in #597236: Add entity caching to core because you can just mock the inner load method and easily define if and how often it should be called. Maybe that would be an easier way to test it?
Downside is that unit tests are always a bit constructed, and it's kind of an integration test here...
That said, very nice work on the tests.
Was wondering if this is really necessary for tests. But it is, because only if we do it like this, we ensure that the random strings are unique.
Comment #7
effulgentsia CreditAttribution: effulgentsia commentedRe #6.0: #1885830-112: Enable static caching for config entities
Re #6.1: #1729812: Separate storage operations from reactions doesn't have a patch yet, so hard to predict what it will mean in relation to which if any hooks should fire before cache clearing and which if any should happen after. As you say, I think what's implemented in this patch, in terms of moving cache clearing to after translation hooks makes sense, and then we can deal with the rest of the question in that issue.
Re #6.2: I prefer it as-is here, since the other tests are also integration tests. But good to know we have a pattern for doing a unit test version if we decide at some point we want that. (and by the way, zOMG, and THANK YOU!!! for driving #597236: Add entity caching to core through to completion!!!!)
Anything else?
Comment #8
BerdirOk, looks good to me, let's get this in, so we can get back the other issue.
Comment #9
alexpottI wonder if it is worth delegating cache key generation to a protected method and moving outside the foreach since there is no need for each ID to be passed to the ConfigFactory::getCacheKey() - we could pass an empty string for all we care.
I also think it might be worth adding a test for disabling overrides missing the cache and then enabling overrides and getting a cache hit and then disabling again and getting a cache hit.
Comment #10
alexpottAlso needs a reroll for #2306455: ConfigEntityStorage adds too many dots since ConfigEntityStorage::getConfigPrefix has become protected and now called getPrefix()
Comment #11
alexpottSomething like this.
Comment #12
effulgentsia CreditAttribution: effulgentsia commentedWhile that happens to work for ConfigFactory's implementation, doesn't that violate the contract of ConfigFactoryInterface, which documents the method as needing a config object name? Even ConfigFactory itself doesn't optimize in that way in its own loadMultiple(). Should we change the API of ConfigFactoryInterface::getCacheKey() to not take a parameter at all and return a key suffix rather than a full key?
Comment #13
alexpottYeah I think that is a good option. Plus we could look at what actually needs to be on the public ConfigFactory interface.
Comment #14
effulgentsia CreditAttribution: effulgentsia commentedAlrighty. Due to #13, postponing this on #2312135: Rename and protect ConfigFactory::getCacheKey(s)(); add a separate ConfigFactoryInterface::getCacheKeys().
Comment #15
Wim Leers#2312135: Rename and protect ConfigFactory::getCacheKey(s)(); add a separate ConfigFactoryInterface::getCacheKeys() just landed, this is now unblocked!
Comment #16
effulgentsia CreditAttribution: effulgentsia commentedFixed to incorporate that issue.
Also, renamed
_loadToken
to_loadStamp
, because I think that more accurately describes it.Comment #17
Wim LeersThe test coverage looks solid to me. Only minor stuff and nitpicks.
Isn't this tied to a single entity type, i.e.
ConfigEntityType
? Is it then still sensible to perform this check?I like how everything moves from
ContentEntityStorageBase
toEntityStorageBase
: consistency FTW! :)Why can't this be a unit test?
I've been told that I should never use
entity_load()
anymore, but<EntityTypeId>::load()
instead. Since this tests always uses$this->entityTypeId === 'config_test
, can't this be changed toConfigTest::load()
?Comment #18
effulgentsia CreditAttribution: effulgentsia commentedThanks for the review. Setting to needs work for #17.4.
Re #17.1: yes, that's still needed, because some config entity types (e.g., Role) might want to enable static cache while others don't.
Re #17.3: I can't find any examples in HEAD where testing anything on the ConfigTest / config_test entity type is a unit test. I'm guessing cause unit tests can't depend on modules? Or maybe there's a way and all those other ConfigTest tests are just old? If you think it's doable, can you point me in the right direction for how? But additionally, we're doing load() and save() as part of these tests, so I don't know how hard it would be to mock all that.
Comment #19
Wim LeersRE: #17.1: ok, that makes sense, thanks.
RE: #17.3: then let's not hold up this patch on that.
#17.4 is a nitpick, so it'd be silly to delay this patch for that. But at the same time, I'm not at all deeply familiar with the config system, so it'd be great if somebody more familiar with the config system could do the final review.
Comment #20
Gábor HojtsyI think its better to not do this as a unit test since we would need to mock way too much of what we actually want to test here. This is about interaction of several pieces. Otherwise looks good and resolves prior concerns.
Comment #23
Gábor HojtsyRandom fail.
Comment #26
Gábor HojtsyComment #27
webchickCommitted and pushed to 8.x. Thanks!
Comment #29
mradcliffeThis change broke Postgresql even more. I think this is due to the changes from ContentEntityDatabaseStorage to EntityDatabaseStorage.
I think it's possible that the resetCache call in ContentEntityDatabaseStorage will create the cache table for the first time, and since that doesn't happen, it fails on other things in the installation.
Comment #30
mradcliffeAdding the WIP patch for mimicking implicit commits in transactions allows Postgresql to continue through the install, but that requires a lot of testing because of what it does. See #2181291: Prevent a query from aborting the entire transaction in pgsql.
I guess that this patch clears the cache inside a transaction (like most entity save operations), which is going to fail hard because the cache table has not been created yet. The transaction is completely rolled back and no other queries are allowed.
Comment #31
mradcliffeI'll keep this open, but we shouldn't revert the commit.
Comment #32
bzrudi71 CreditAttribution: bzrudi71 commentedYup, this needs some work ;-) PostgreSQL testbot exceptions before patch ~240 - after patch ~1440. All errors are about:
Comment #33
effulgentsia CreditAttribution: effulgentsia commentedMaybe I'm missing something, but from what I can see, HEAD was doing the same prior to #16 as well. The only change I can see is that the cache reset is now happening after
$this->invokeTranslationHooks($entity);
(which is also currently inside the transaction, both before and after the patch) instead of before.Comment #34
mradcliffeThanks for keeping this open as a reminder. Closing as other issue was committed.