[Zope-CMF] Re: five.intid and DirectoryView

Ross Patterson me at rpatterson.net
Mon Jun 30 13:34:58 EDT 2008


Laurence Rowe <l at lrowe.co.uk> writes:

> Ross Patterson wrote:
>> Tres Seaver <tseaver at palladion.com> writes:
>>
>>> Martijn Pieters wrote:
>>>> On Fri, Jun 27, 2008 at 6:53 PM, Ross Patterson <me at rpatterson.net> wrote:
>>>>> "Martijn Pieters" <mj at zopatista.com> writes:
>>>>>> But the code never does that. When cloning a file-based FSObject, a
>>>>>> new instance is created and that is added to the ZODB. Noone else
>>>>>> should do this either.
>>>>> zope.app.keyreference does.  The persistence machinery doesn't add an
>>>>> object to a connection until commit.  As such, an IPersistent and
>>>>> IObjectAdded event handler, such as the one in zope.app.intid, that
>>>>> needs the object to have a connection needs to add the object to a
>>>>> connection.
>>> Sounds like a bug in zope.app.intid to me:  it shouldn't be forcing
>>> objects to have connections.
>>>
>>>> Why is the IObjectAdded event fired at all? Perhaps that's the bug here.
>>>>
>>>>> Shouldn't anything that implements IPersistent be able to be added to a
>>>>> connection?  Wouldn't that be considered part of providing the
>>>>> interface?  Where else is an object that provides IPersistent stored in
>>>>> global state?
>>>> I assume it was easier at the time to use just one class. Perhaps this
>>>> should be reconsidered now. However, just providing the IPersistence
>>>> interface does not mean the object expects to be added to a connection
>>>> arbitrarily.
>>> Exactly.  Nobody is supposed to add objects to a connection except their
>>> already-persisted containers.
>>
>> That sounds right to me especially given that an object's parent isn't
>> necessarily "where" the object is persisted.  Shouldn't it be possible,
>> for example, to have a container that looks up it's contained items from
>> a utility that actually is stored in another ZODB.  Such a container's
>> items would not share their parent's connection.
>>
>> FWIW, this happens in zope.app.keyreference.  The reason it needs the
>> object to have a connection is so that it can get the object's _p_oid.
>> If this is a bug, how can zope.app.keyreference get _p_oid for an object
>> added in the current, as yet uncommitted transaction?
>
> Creating a savepoint seems to do the trick:
>
>>>> from persistent import Persistent
>>>> import transaction
>>>> app.pob = Persistent()
>>>> app.pob._p_oid is None
> True
>>>> s = transaction.savepoint()
>>>> app.pob._p_oid
> '\x00\x00\x00\x00\x00\x00E\xfa'

Would that be a problem causing ZODB bloat?  Say if the object were
deleted later in the same transaction?  Would it slow down transactions
adding large numbers of IPersistent objects?

Can anyone else see any other potential problems with using savepoints
instead of manually adding objects to a transaction?  If my questions
aboved are all resolved, should the implementation of
zope.app.keyreference (and five.intid) be changed?

Ross



More information about the Zope-CMF mailing list