Changeset 1832

Show
Ignore:
Timestamp:
10/31/08 18:15:15 (2 months ago)
Author:
slinkp
Message:

FIXED ConflictErrors on MemberInfo, with a long comment about the problem. Still have conflicts in a couple other places though.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • siteapp/trunk/opengeo/almanac/member.py

    r1797 r1832  
    205205        self.fullname = fullname 
    206206        self.location = location 
     207 
     208    def __setattr__(self, name, value): 
     209        # XXX Horrible hack to avoid ConflictErrors. 
     210        # The problem is that the adaptation IMemberInfo(principal) 
     211        # eventually leads to calling: 
     212        # zope.location.location.located(memberinfo, principal, 
     213        #   name='...MemberInfo') 
     214 
     215        # ... which checks whether principal is object.__parent__, and 
     216        # if not, calls zope.location.location.locate() which re-sets 
     217        # the memberinfo's __parent__ and __name__ attributes.  And 
     218        # for some weird reason, we have two instances of the same 
     219        # principal and they are not the same object.  In other words, 
     220        # zope.location is broken when the parent is a principal. So 
     221        # we mutate the persistent MemberInfo on every request for no 
     222        # reason, even when anonymous -- which leads to ZODB bloat and 
     223        # frequent ConflictErrors.  To avoid that, we don't save those 
     224        # attrs unless the new values are different. 
     225        if name == '__name__' and self.__name__ == value: 
     226            return 
     227        elif name == '__parent__': 
     228            # principals don't define __eq__, so compare their attributes. 
     229            if self.__parent__.__dict__ == value.__dict__: 
     230                return 
     231        # Persistent.__setattr__() is where _p_changed is set True, 
     232        # so if we bail out before this, the object is not marked dirty. 
     233        super(MemberInfo, self).__setattr__(name, value) 
    207234         
    208235member_info_annotation = factory(MemberInfo)