Jim Fulton wrote:
Martijn Faassen wrote:
What is stored in the ZODB are LocationProxy wrapped objects.
I think you mean ContainedProxy objects.
Yes, I imagine so.
The location proxy wrappers get a unique id reference in the IntId
utility, not the objects themselves. Now when you send an
ObjectModificationEvent from one the document's *own methods*, the
event is sent with as payload to catalog something that is not
proxy wrapped. This means that the int id can never be found for
this object, and thus the reindexing cannot take place properly.
I think what's happening is that ContainedProxy objects are
persistent and thus get a key reference, and this an intid that is
distinct from the object they proxy.
Exactly, that's our diagnosis too.
This basically means that LocationProxy wrapped objects cannot
reliably respond correctly to ObjectModificationEvents, and thus
won't be cataloged correctly. If the ObjectModifiedEvent is sent by
methods inside the object itself, things will fail, if the
ObjectModifiedEvent is sent by code elsewhere, they'll likely work.
This is all fixed by subclassing Contained,
which avoid the ContainedProxy.
Right, so no proxy being cataloged.
but the catalog not working
reliably for LocationProxy wrapped objects sounds scary. You could
do something with the IntId utility automatically
un-location-proxy-wrapping the objects if necessary, but that would
mean that what is stored wouldn't know its location anymore, which
would also be bad.
I'm a bit puzzled that your content object's methods are geberating
Well, it is, and my point is that this leads to quite unexpected
behavior; i.e. the object not being cataloged silently.
If an object doesn't participate in the location framework, then we
have to create a second object that provides location, the
ContainedProxy. There are really two distinct objects. You want the
intid to point to the proxy, so you get the location information.
The content object knows nothing about the proxy, so it can't
generate events about the proxy.
My suggestion is to do one of:
- Implement ILocation in your content objects. This is the simplest
course. It sounds like, for your application, the content objects
should know about their locations, since you want them to be able to
generate events that contain location information.
Right, and we ended up doing so. Not doing so was a mistake (and my
fault). I just thought after the debugging session that it's a bit of a
dead chicken to have to provide the interface to make the catalog work
as expected. It took quite a bit of hard thinking to understand what was
really going on, as everything else appeared to work. This is not a good
thing a programmer has to deal with.
A scenario that could easily happen is the following:
* an application is built, and IContained is not implemented.
* users add lots of content objects.
* now in a new iteration of the application, it's decided to add catalog
* now (after debugging why cataloging appears to fail mysteriously) the
programmers discover they have to go back and somehow get rid of the
ContainedProxy wrappers in the ZODB.
- Don't generate events amout the located objects (e.g. modification
events) from within content object methods. The content objects don't
have enough information. Rather, generate the events from views on
the objects obtained from the container.
Right. I just think it's not very programmer-friendly to have the
catalog fail silently because IContained is not being implemented. I
wish there were some way to make the catalog either not fail, or
alternatively fail noisily. I haven't thought of such a way yet though,
but it'd be nice. Proxies making ones life difficult smells a bit too
much like Zope 2. :)
Zope3-dev mailing list