Optimize reindexObjectSecurity: bypass processQueue mid-request#155
Conversation
b6fdfaf to
2c96c0f
Compare
Add CatalogTool._unrestrictedSearchResults that calls ZCatalog.searchResults directly without processQueue(). Use it in reindexObjectSecurity with a getattr fallback for custom catalog tools. Refs #152
2c96c0f to
af90917
Compare
|
@davisagli At this point (no offense) I would like to have a second opinion before merge |
|
@jensens I would like to review this but it might take me a day or two to get to it. |
davisagli
left a comment
There was a problem hiding this comment.
I think this should be okay (aside from the possible warnings re deleted objects that I mentioned in #152 (comment))
|
I have released this in They pass again when I use a checkout of It could be that the broken tests just need to be fixed, but there are 6 of them, divided over 4 packages, so maybe the change really is not sufficient. Sample failures: and: @jensens Can you have a look please? Meanwhile I have reverted the CMFCore pin in Plone 6.2. |
|
I quickly checked. This log line that got changed from warning to debug level, does not get triggered in the failing tests: I put a breakpoint in there, but it never happened. So we have no indication of a problem there. |
When the indexing queue is processed outside a request context (e.g. in the before_commit transaction hook), getSite() returns None. IndexableObjectWrapper then falls back to the global site manager, which lacks locally registered indexer adapters. This causes attributes like exclude_from_nav to silently not be indexed. Previously masked because processQueue() was called mid-request (via reindexObjectSecurity -> unrestrictedSearchResults) when the site was always set. Since #155 bypasses processQueue in reindexObjectSecurity, more operations are deferred to before_commit where the site may not be set. Fix: PortalCatalogProcessor._ensure_site() walks the object's acquisition chain to find and activate a site before each catalog operation. Refs: plone/buildout.coredev#1080 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the indexing queue is processed outside a request context (e.g. in the before_commit transaction hook), getSite() returns None. IndexableObjectWrapper then falls back to the global site manager, which lacks locally registered indexer adapters. This causes attributes like exclude_from_nav to silently not be indexed. Previously masked because processQueue() was called mid-request (via reindexObjectSecurity -> unrestrictedSearchResults) when the site was always set. Since #155 bypasses processQueue in reindexObjectSecurity, more operations are deferred to before_commit where the site may not be set. Fix: PortalCatalogProcessor._ensure_site() walks the object's acquisition chain to find and activate a site before each catalog operation. Refs: plone/buildout.coredev#1080
Summary
Builds on #154 (revert of tree-walk approach).
_unrestrictedSearchResultstoCatalogTool— callsZCatalog.searchResultsdirectly, bypassingprocessQueue()reindexObjectSecurityto use the new method withgetattrfallback for custom catalog toolsFollows the existing
_indexObject/_reindexObject/_unindexObjectconvention for queue-bypassing counterparts.Objects still in the indexing queue don't need to be found: their pending
INDEXoperations will include the current security state when processed at transaction commit time. see #152 (comment)Benchmark
With a clean queue (no pending operations), performance is identical (~0.5ms).
With a dirty queue (pending reindex operations from mid-request modifications), bypassing
processQueue()avoids a costly flush:Fixes #152