-
-
Notifications
You must be signed in to change notification settings - Fork 824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Afform - improve loading performance #27783
Conversation
🤖 Thank you for contributing to CiviCRM! ❤️ We will need to test and review this PR. 👷 Introduction for new contributors...
Quick links for reviewers...
|
6b7e1d0
to
b600d09
Compare
@colemanw Questions:
My recollection is that it originally aimed to cache indexes (scans/metadata) while the main data would use clean reads. In principle (aka in the theory at the time), a typical page-load should be a limited set of afforms (say, 5 afforms) -- and 5 calls to But I haven't read this in a while, and obviously things change, so it needs a fresh read. |
$cacheValue = ChangeSet::applyResourceFilters($this->getChangeSets(), 'partials', $this->getRawPartials($name)); | ||
$this->cache->set($cacheKey, $cacheValue); | ||
if (!isset($this->partials[$name])) { | ||
$this->partials[$name] = ChangeSet::applyResourceFilters($this->getChangeSets(), 'partials', $this->getRawPartials($name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, cool. So it looks like it would still be reading live HTML files. It's just using $this->partials
(array
) instead of CRM_Utils_Cache_ArrayCache
.
Well this only caches module metadata, not the html partials themselves if that's what you mean. But I suppose if you are a developer and decide to change angular metadata via your filesystem and then you decide not to clear caches and expect freshness... I dunno what to tell you.
I'm not sure but I can tell you how performance improves. The bottom line is that we'll be hitting the sql cache the same amount before & after, but now that cache includes all angular metadata instead of just the afform dependency graph. This means we no longer have to call |
b600d09
to
17332d6
Compare
e06c803
to
114cac7
Compare
114cac7
to
f7b8647
Compare
f7b8647
to
b5dcb41
Compare
Before: Angular modules were not cached, afform loading was slow After: Cache previously used for afform dependencies now used for all Angular modules
b5dcb41
to
6af23f8
Compare
I did some light |
Overview
This PR makes a few big changes and several small changes to the loading of Afforms in-particular, and Angular Modules in-general, with the goal of improving efficiency and consistency.
Technical Details
Before: One
SqlGroup
cache is used to store Afform dependencies, but everything else about loading Angular modules (callinghook_civicrm_angularModules
, scanning all extensions and directories for Afforms, dispatching'civi.afform.get'
) happens at least once per page load (and is cached in a static array).After: One
SqlGroup
cache is used to store all Angular modules (including Afform dependencies). So none of the above has to happen on every page load.Before:
API.Afform.get
would delegate permission checks to another function... which in turn would callAPI.Afform.get
! Amazingly this somehow avoided an infinite loop but was still pretty weird.API.Afform.checkAccess
wasn't working at all.After: Afform permission checks are still centralized, but without the weird loop.
API.Afform.checkAccess
works and has a test.Before:
AngularDependencyMapper
relies on file scanning, so Afforms provided via hook ('civi.afform.get'
) are left out.After: All Afforms are scanned for dependencies regardless of how they're provided. The
AngularDependencyMapper
class is greatly simplified because the bulk of it was dedicated to file scanning and cache management. Since caching is now handled at the level of Angular modules, it's not needed in this class.modified_date
returned byAPI.Afform.get
(reading fromfilemtime()
was a by-product of the old caching mechanism inAngularDependencyMapper
which I've ripped out but thought I'd keep that bit of useful info and output it from the API)Comments
I keep being surprised every time I notice that we don't actually cache angular module info. I always assume that we do and I think the aspiration was to cache it but it just never got implemented. Lots of code acts as though a cache exists, for example, this function didn't have to change at all...
civicrm-core/ext/afform/core/afform.php
Lines 487 to 491 in 3ee3a88
... that was being called to clear the (nonexistent) Angular module cache every time an Afform is saved. Well, now it actually does something!