[ZODB-Dev] [Problem] "_v_" variables too volatile

Toby Dickenson tdickenson at geminidataloggers.com
Wed Dec 10 13:12:05 EST 2003


On Wednesday 10 December 2003 16:17, Jeremy Hylton wrote:

> > There
> > are cases where I set _v_ variables (and in fact it's most cases) where I
> > could care less if the object is flushed on subtransactions. IOW I think
> > using _p_dont_deactivate should be the exception and not the rule.

I suspect you believe this is safe because you are assuming that the cache 
collector will never be activated at some points in your code, and you are 
assuming that the cache collector will only be triggered by a subtransaction.

That assumption might be true in some limited cases today, but it is brittle. 
Im sure something would break if code making this assumption was mixed with 
some of my cache-hungry Zope Products.

It will certainly not be true in future.... The extreme case is when we allow 
the cache can trigger some deactivations itself, to prevent it ever growing 
too large. I am assuming that what we design for volatile attributes today 
will need to cope with this.

For example, the following code would be unsafe, because self might get 
deactivated (removing all _v_ attributes) between the hasattr check and using 
_v_bar.

    def foo(self):
        if not hasattr(self,'_v_bar'):
            self._v_bar = self._make_bar()
        ....use some other persistent objects
        ....and self._v_bar at the same time.


I agree there are points in the lifetime of an object that uses _v_ attributes 
where it can state that it no longer assuming that its _v_ attributes will 
disappear arbitrarily. In Dieters original proposal, we need to support 
self._p_keepv=0 . For safety, Im sure we need for any _v_ assignment to 
automatically turn it on.

I suspect it is true that much (but not all) of your code using _v_ attributes 
could be rewritten to be safe under this type of cache management. For 
example, the code above could be converted to:

    def foo(self):
        try:
            bar = self._v_bar
        except AttributeError:
            bar = self._v_bar = self._make_bar()
        ....use 'bar' and some other persistent
        ....objects at the same time

Note that the self._v_bar attribute might have disappeared by the end of the 
function, but the 'bar' local will not. Unfortunately no code using _v_ 
attributes today is prepared to defend against this.

> > Explicit is better than implicit.

Safe-by-default is better than explicit

I hope that all makes sense....

-- 
Toby Dickenson




More information about the ZODB-Dev mailing list