Lifecycle Event Subscribers¶
A set of subscribers for the object zope.lifecycleevent
events.
These subscribers take care of registering and unregistering objects
with all available IIntIds
utilities
when IObjectAddedEvent
and
IObjectRemovedEvent
events are
fired, respectively.
These subscribers and events are modeled on those that come with
zope.intid
and are intended to be used (optionally) as drop-in
replacements for them. This allows zc.intid to work in conjunction
with things written for zope.intid
, such as
zope.catalog
.
In particular, a few things are done just like zope.intid
:
- We do ensure that the object can be adapted to
IKeyReference
before doing any processing (even though we don’t register that in the utility or otherwise use it.) In the common case of persistent objects, this will ensure that the object is in the database and has a jar and oid, common needs. - We do broadcast the events from
zope.intid.interfaces
, even though the utility will broadcast its own events. Thus these subscribers generate at least three events for every lifecycle event.
Configuring¶
To configure, you need to include subscribers.zcml
, while being
careful about how zope.intid
is configured:
<!-- configure.zcml -->
<!--
If we load zope.intid, we get subscribers for the Object events
that ensure all ILocation objects are registered/unregistered when
they are added/removed, plus another set of events when they
get/lose intids. This second set of events is meant to update
zope.catalog. A consequence of this is that ILocation objects must
be adaptable to KeyReferences when they are ObjectAdded (for
purposes of zope.intid, which we don't care about, but this also
ensures that they have ZODB Connections, which is good).
We cannot use these subscribers as-is due to the way the use IKeyReference
and try to register that. However, our subscribers *do* make sure that
the given objects can be adapted to IKeyReference because that's useful and
may be required by catalogs or other subscribers.
-->
<exclude package="zope.intid" file="subscribers.zcml" />
<include package="zope.intid" />
<!-- Make sure the default IKeyReference adapters are in place -->
<include package="zope.keyreference" />
<include package="zc.intid" />
<!--
Make zc.intid utilities compatible with zope.intid utilities.
-->
<include package="zc.intid" file="zope-intid.zcml" />
<!-- To hook them up to the Object events, we need to include the file -->
<include package="zc.intid" file="subscribers.zcml" />
KeyReferences and zope.intid¶
These subscribers do not register/unregister a IKeyReference
with the intid utilities. Instead, it registers the actual object, and the
events that are broadcast are broadcast holding the actual object.
IKeyReferenceces
, especially
KeyReferenceToPersistent
, are
used for a few reasons. First, they provide a stable,
object-identity-based pointer to objects. To be identity based, this
pointer is independent of the equality and hashing algorithms of the
underlying object. Identity-based comparisons are necessary for the
classic zope.intid
utility implementation which uses a second
OIBTree
to maintain the backreferece from object to assigned intid
(clearly you don’t want two non-identical objects which happen to
compare equally now to get the same intid as that condition may
change). Likewise, these references are all defined to be mutually
comparable, no matter how they are implemented, a condition necessary
for them to all work together in a OIBTree
. Lastly, these
references are meant to be comparable during ZODB conflict resolution
(the original persistent objects probably won’t be), which, again, is
a condition of the implementation using a OIBTree.
A consequence of avoiding these references is that generally
persistent objects that are expected to have intids assigned should
not be used as keys in an OxBTree
or stored in an OOSet.
Instead, all such data structures should use the integer
variations (e.g., IISet
), with the intid as the key.
Subscriber Functions¶
-
zc.intid.subscribers.
addIntIdSubscriber
(ob, event)[source]¶ Registers the object in all unique id utilities and fires an event for the catalogs. Notice that each utility will fire
zc.intid.interfaces.IIdAddedEvent
; this subscriber will then fire one singlezope.intid.interfaces.IIntIdAddedEvent
, followed by one singlezc.intid.interfaces.IAfterIdAddedEvent
; this gives a guaranteed order such thatzope.catalog
and other Zope event listeners will have fired.
-
zc.intid.subscribers.
removeIntIdSubscriber
(ob, event)[source]¶ Removes the unique ids registered for the object in all the unique id utilities.
Just before this happens (for the first time), an
zc.intid.interfaces.IBeforeIdRemovedEvent
is fired, followed by anzope.intid.interfaces.IIntIdRemovedEvent
. Notice that this is fired before the id is actually removed from any utility, giving other subscribers time to do their cleanup.Before each utility removes its registration, it will fire
zc.intid.interfaces.IIdRemovedEvent
. This gives a guaranteed order such thatzope.catalog
and other Zope event listeners will have fired.