#239: Adapterise the Extensible Indexable Object Wrapper

Contents
  1. Motivation
  2. Proposal
  3. Risks
  4. Progress log
by Martin Aspeli last modified Jan 21, 2010 07:28 AM

Make it easier to register ExtensibleIndexableObjectWrapper attributes with adapters

Proposed by
Martin Aspeli
Proposal type
Architecture
Assigned to release
State
completed

Motivation

Custom indexing strategies currently rely on a global registry of "fake" attributes to the indexable object wrapper. It would be more natural and flexible to be able to register adapters for any context that can provide values for indexable attributes.

Proposal

  1. Create a new package, plone.indexer
  2. Here, define an interface, IIndexer, which looks like this:
    class IIndexer(Interface):
        def __call__(self):
            """Return the value to index.
            """
    The idea is that you register an adapter that adapts your content type (self.context) and the catalog (self.catalog) and provides IIndexer, with the name of the indexable attribute.
  3. Create a convenience @indexer decorator to allow simpler indexers like the following:
    @indexer(IMyType)
    def my_indexer(object):
        return ...
  4. Create a standard IndexableObjectWrapper implementation that looks up such adapters when asked to provide indexable attributes.
  5. Update CMFPlone's CatalogTool to use this wrapper
  6. Deprecate registerIndexableAttribute() and make it register delegate adapters for now.

 

Risks

We may find that doing an adapter lookup for each attribute that gets indexed is slower than finding a function in a global dict, as it is now. Hopefully, the zope.component cache will solve this, but we should benchmark.

Progress log

Done:
  • plone.indexer written and tested
  • Plone branch created and relevant tests updated
  • BBB code in place
Outstanding:
  • Deprecate plone.app.content.interfaces.IIndexableObjectWrapper as an alias for plone.indexer's version of the same (we can do this post-merge)

Cost of adapter lookups

Posted by Sidnei da Silva at Sep 29, 2008 03:43 AM
It's undeniable that doing adapter lookups *will* be slower than looking up global functions. The question is: how cacheable are adapter lookups and what can be done to make them even more cacheable?

For example, if you take many objects that are based on the same class, if they have no 'directlyProvided' interfaces (a.k.a. marker interfaces) there's no reason at all for the lookup to be different between two random objects of this set. Maybe the adapter lookup can be short-lived and cached at a higher level, closer to the place where this is used, when indexing/reindexing many objects.

Reduce pain of catalog metadata - content collisions

Posted by David Glick at Oct 15, 2008 08:56 PM
I just spent several very confused hours debugging some weird behavior that turned out to be the result of the catalog trying to fetch metadata from an attribute which ended up getting acquired from a content item (in the container) with the same name. This PLIP is thus sounding pretty nice right now, as it would help prevent this scenario.

Framework team vote

Posted by Martijn Pieters at Oct 26, 2008 04:55 PM
+1

Framework team vote

Posted by Danny Bloemendaal at Oct 27, 2008 03:53 PM
I refrain from voting on this one.

Framework team vote (for Plone 3.3)

Posted by Andreas Zeidler at Oct 27, 2008 09:49 PM
+1 (anything that makes indexing more sane is highly welcome :))

Framework Team vote

Posted by Tom Lazar at Oct 28, 2008 10:40 AM
+1 although the BBB would still allow for the pain that David Glick mentions (and which we probably all have experienced already, i certainly have...) i still think that the change is worthwhile and a step in the right direction.

Acquisition

Posted by Alec Mitchell at Jan 08, 2009 02:11 AM
I'm all for this! Though I'd like to comment on a couple of the comments.

As far as performance goes, I'd be very surprised if this change has a noticeable impact. Indexing (which is the only time these adapters will be looked up) does not happen frequently and tends to be a relatively slow operation. The additional impact of a single adapter look-up on an already relatively slow and rare index update is likely to be incredibly small. We probably perform thousands of adapter look-ups on a single page render, but rendering a page can easily take less time than it takes to reindex an object.

Though the behavior David mentions can sometimes cause unexpected behaviors, they are exactly the sorts of problems one expects from acquisition :-) I'd say that the existing behavior of indexing acquired attributes is exactly should happen in a system that uses acquisition in the way that Zope 2 does. I'm certain that there are many users relying on the fact that catalog indexes/metadata use acquired attributes in a manner consistent with the content objects. As a result, I think it would be unwise and undesirable to change this behavior.

Framework team vote (for merging into Plone 3.3)

Posted by Andreas Zeidler at Jan 28, 2009 02:34 PM