January 30 2008posted by Santi

Cataloging and indexing in CPS

For Zope developers is usual to inherit from CatalogAware and overload index_object or reindex_object methods. In CPS, due to the existence of a IndexationManager, that does this work. The main reason of this manager is ensure that object indexation is done just once per object and transaction, resulting in a better performance. All this is explained in CPSCore/doc/transaction_managers.txt

It's important to have this in mind when we want to index attributes calculated from other objects. For instance, if we have a Task object with a planned start date and a planned end date, and this dates should be obtained from the tree of subtasks, when existing, we should force reindex of parents when a subtask changes. If the method calculating the start date from children tree relies on the catalog, then it is specially important the order how the subtasks are pushed to the IndexationManager to be cataloged.

The better approach we have found to solve this case is call reindexObject from the postCommitHook method. That reindexObject simply pushes the object to be indexed later, at the end of the transaction. Here there is an example:


def postCommitHook(self, datamodel=None):
"""
Our parents could have some fields calculated from our. So, if our
parent is a KMKey Task or KMKey Project Proxy, then reindex it
"""
super(KMUnit, self).postCommitHook(datamodel)
proxy = IKMProxyFinder(self).getProxy()
# Store first a reindex of myself, so CPS IndexationManager process it
# before our parents
proxy.reindexObject()
proxy = proxy.aq_parent
while ICPSProxy.providedBy(proxy) and IKMUnit.providedBy(proxy.getContent()):
proxy.reindexObject()
proxy = proxy.aq_parent