The getResourcesOfType method in ContentHostingService (from
SAK-11535) helps performance when assembling a portfolio, but still retrieves and checks every completed form in the system for type and permission. This becomes quite slow at scale due to multiple database roundtrips for every form, regardless of user. At Michigan, we are experiencing page load times approaching one minute.
This is a tricky issue because of service boundaries. The StructuredArtifactFinders search for a given type of form, which is a metaobj notion. ContentHostingService and SecurityService only work together to return a permission-checked list of ContentResources of the generic metaobj type.
There are two core issues here:
1. Every form in the system is checked for permissions before being filtered by type, generally checking many irrelevant items.
2. Every form is checked for permissions individually by looping rather than by set, issuing many queries.
Resolving the first issue would require ContentHosting to be able to discern between form types, ideally by query, but at least by filtering. This may be resolvable by passing a filtering predicate.
Resolving the second issue would be more involved and needs discussion. At issue is whether checking only collections that are currently available to the user is sufficient, as well the lack of an efficient means to check unlock for a set of references across collections.
The very simple patch attached eliminates one round trip per item by caching the already-retrieved entities before calling unlockCheck on them. This changes the profiled downstream time distribution between SecurityService.unlock() and BaseContentService.availabilityCheck() from roughly 53/47 to 98/0.