Wichert Akkerman <[email protected]> writes: > I am just catching up on Ross's work last week, and I am not sure > about the changes in this changeset: > > http://dev.plone.org/old/collective/changeset/88642/Products.membrane
This changeset was proposed and discussed well in advance. It would have been vastly preferable to bring up debate *before* a contributor put the time in to implement. > I see the problem Ross is trying to solve: generating a list of > everything an object can be adapted to is expensive (which is why the > same thing was removed from the Plone 3.x tree just before 3.0). > > This solution moves the penalty to the developer: instead of only > having to write an adapter developers are now forced to register both > an adapter and a new marker interface. I feel quite strongly that this > repetition is not desirable, so I want to investigate alternatives. If by "register" you mean the "<interface>" registration, the developer would not need to do that. All the developer would need to do is make sure the class implements the marker interface which can be done in the class level implements declaration or in ZCML. This is one of the most simple declarations possible. > A trivial alternative is to add some simple caching to the > object_implements method. If we cache based on class and directly > provided interfaces we should get the exact same results while having > almost no noticeable performance problems. This might even allow us to > simplify the code and only use the slow-but-readable code path I don't think caching should be used to solve a problem where code is doing too much. In this case, I think this is a matter of explicit vs. implicit. The previous implementation was implicit, tried to do too much, and it's performance problems stemmed from its implicitness. I think an explicit implementation is better than a caching implementation that tries to do too much and then hides that fact. Consider someone who builds a sub-typing membrane implementation where content has interfaces applied to individual member content that results in those object then *becoming* adaptable to one of these interfaces. With a caching solution, we require them to invalidate the right cache. With the explicit marker interface solution, we provide the developer the way to say explicitly, "this object should now be able to proivide this membrane capacity". The latter seems much more humane, clearer, less surprising, and more maintainable. > Plone offers a fairly rich system of catalog indexing helper routines > which we can leverage. Instead of iterating over the ZCA registrations > to build a list of interface an object implements or can be adapted to > we can do simpler things. For example we could have a feature catalog > that looks like this: With the current implementation, we don't iterate over the ZCA registrations, we lookup interfaces that have been registered as providing the IMembraneQueryableInterface. > @indexer(Interface, membrane_tool.IMembraneTool) > def features(obj): > _features = dict(user = IMembraneUserObject, > auth = IMembraneUserAuth, > props = IMebraneUserProperties) > > result=[] > for (ft, iface) in _features.items(): > a=iface(obj, None) > if a is not None: > result.append(ft) > return ft > > This should be fast enough for indexing purposes since we can use all > the fast paths and optimisations from the ZCA, and gives us much > simpler catalog data: we will no longer need to index all the > interfaces that are not relevant for membrane. There is an obvious > optimization here: if an object does not adapt to IMembraneUserObject > we can short-circuit and stop processing immediately. But it is not as easily extensible. With the interface utilities approach, used in zope 3 in several places BTW, it's much easier to add "features". Ross -- Archive: http://www.coactivate.org/projects/remember/lists/remember/archive/2009/06/1246286978275 To unsubscribe send an email with subject "unsubscribe" to [email protected]. Please contact [email protected] for questions.
