hvelarde
(hvelarde)
July 21, 2017, 3:14pm
1
I'm working on a PR to fix an issue on an add-on and I'm facing a weird behavior in the catalog of latest Plone 5.1 branch:
part of the fix involves reindexing the catalog in order to reflect a new behavior that was just added on a previous version; the code to test this upgrade step looks like this:
from sc.social.like.behaviors import ISocialMedia
from sc.social.like.tests.utils import enable_social_media_behavior
with api.env.adopt_roles(['Manager']):
for i in xrange(0, 10):
api.content.create(self.portal, 'News Item', str(i))
# break the catalog by deleting an object without notifying
self.portal._delObject('0', suppress_events=True)
self.assertNotIn('0', self.portal)
enable_social_media_behavior()
results = api.content.find(object_provides=ISocialMedia.__identifier__)
self.assertEqual(len(results), 0)
as you can see I'm creating 10 instances of a content type, after that I'm applying a behavior to it; this change must not be reflected in the catalog because enabling the behavior should not fire an object reindex at all.
the assertion pass normally in Plone 5.0 (ZODB 3.10.7) and fails in Plone 5.1 (ZODB 5.2.4).
any hints?
BTW, this is the code for enable_social_media_behavior()
:
def enable_social_media_behavior():
fti = getUtility(IDexterityFTI, name='News Item')
behaviors = list(fti.behaviors)
behaviors.append(ISocialMedia.__identifier__)
fti.behaviors = tuple(behaviors)
# invalidate schema cache
notify(SchemaInvalidatedEvent('News Item'))
hvelarde
(hvelarde)
July 21, 2017, 3:48pm
2
Hanno Schlichting pointed out in the ZODB list this could be instead related with this PLIP:
opened 01:56PM - 27 Jan 16 UTC
closed 07:02AM - 08 Jun 17 UTC
22 status: in-progress
03 type: feature (plip)
### Proposer : Gil Forcada
### Seconder : Maik Derstappen
## Abstract
Move … all functionality on existing packages (`Products.ZCatalog`, `Products.CMFCore` and `Products.CMFPlone`) and apply all monkey patches directly to the packages they belong to, like `Products.CMFCore` or `Products.Archetypes`.
## Motivation
Using `collective.indexing` has two main benefits:
- **performance**: indexing operations are queued, optimized and done at the transaction boundary. Only one indexing operation is done per object on any transaction. This means that plone is much faster, specially if lots of event handlers modify objects and keep reindexing the same object over and over again.
- **pluggable**: it creates a utility that enables third-party search indexers to be notified on any indexing operation (that's how collective.solr is plugged-in)
We think they are important and transparent enough that any Plone installation will benefit from it, specially for the performance part, although the pluggable makes even more easier to scale Plone as the site grows.
## Assumptions
Some tests in Plone core will need to be updated to work around the indexing optimizations (as tests expect that objects are indexed/reindexed/unindexed right away).
**No** refactorings will be done on either CMFPlone `CatalogTool` nor CMFCore `CatalogTool` nor ZCatalog `ZCatalog` base class (which both CMFPlone and CMFCore override), this cleanup/refactoring is out of scope.
We deemed more importantly to get the functionality first in rather than merging the catalog tools together. At the same time we encourage any individual/company to step up and propose a PLIP that goes in that direction.
## Proposal & Implementation
- [X] [plip config file on buildout.coredev](https://github.com/plone/buildout.coredev/blob/5.0/plips/merge-collective-indexing.cfg) to track the implementation and branches
- [X] [jenkins job](http://jenkins.plone.org/view/PLIPs/job/plip-collective-indexing) to test the plip config
- [x] move all functionality provided by collective.indexing to currently existing packages ([Products.CMFCore](https://github.com/plone/Products.CMFCore/tree/merge-collective-indexing) and [Products.CMFPlone](https://github.com/plone/Products.CMFPlone/tree/merge-collective-indexing))
- [x] the code of collective.indexing is now GPL and should be re-licensed by the PF-Board to ZPL before getting into CMFCore which are ZPL (@plone/plone-foundation-board)
- [x] add tests where the functionality moved
- [x] fix tests due to the way indexing is done with collective.indexing
- [x] documentation (describe the new feature, how to update tests, how to migrate from collective.indexing)
- [ ] collective.solr branch
- [X] deprecation warning on [collective.indexing](https://github.com/plone/collective.indexing/tree/merge-to-plone-core)
## Deliverables
- CMFCore branch
- CMFPlone branch
- documentation on how to fix your tests and how the new functionality benefits Plone
- collective.solr branch (as is collective.indexing main consumer)
- new release of collective.indexing with deprecation warnings
## Risks
Some tests of 3th party packages can fail, but are easy to fix, with the processing_queue function which will be provided.
## Participants
Gil Forcada
Maik Derstappen
here is his reply:
On 07/21/2017 12:34 PM, Hanno Schlichting wrote:
It's pretty unlikely changes in the ZODB would result in a single test
failure in a Plone catalog.
I'd say the more likely culprit is the inclusion of collective.indexing.
I think its code got merged into the CMF/Plone catalog tools for Plone
5.1.
Maybe you could try to get a hold of the index queue and peek into it,
and see what that gives you
(Products.CMFCore/Products/CMFCore/indexing.py at 2.3 · zopefoundation/Products.CMFCore · GitHub ).
@gforcada @MrTango do you mind to take a look at this issue?
gforcada
(gforcada)
July 22, 2017, 8:22am
3
You could try to use the environment variable described here:
.. _using_external_catalogs:
=======================
Using external catalogs
=======================
.. admonition:: Description
The Plone catalog can be extend to use external catalogs like Solr or Elasticsearch.
Add-ons like collective.solr use that to hook into the catalog API and do some Indexing outside of Plone in Solr,
which increases performance and flexibility of indexing a lot.
Implement IIndexingQueueProcessor
---------------------------------
To hook into the catalog one can implement the IIndexingQueueProcessor
`interface from Products.CMFCore <https://github.com/zopefoundation/Products.CMFCore/blob/master/Products/CMFCore/interfaces/_tools.py>`_.
This file has been truncated. show original
i.e.
CATALOG_OPTIMIZATION_DISABLED=y ./bin/test
Or, you could manually process the queue:
from Products.CMFCore.indexing import processQueue
...
do some operations that will trigger catalog indexing operations
...
processQueue()
check that the operations took place
I hope this helps
3 Likes
hvelarde
(hvelarde)
July 24, 2017, 1:54pm
4
thanks! that made the trick and tests are now passing.
2 Likes