[Zope-CVS] CVS: Products/AdaptableStorage/serial/interfaces - IAspectEvent.py:1.2 IFullDeserializationEvent.py:1.2 IFullSerializationEvent.py:1.2 IObjectSerializer.py:1.5

Shane Hathaway shane@zope.com
Fri, 13 Dec 2002 15:42:33 -0500

Update of /cvs-repository/Products/AdaptableStorage/serial/interfaces
In directory cvs.zope.org:/tmp/cvs-serv32288/serial/interfaces

Modified Files:
	IAspectEvent.py IFullDeserializationEvent.py 
	IFullSerializationEvent.py IObjectSerializer.py 
Log Message:
Hopefully solved the problem of unmanaged persistent objects.

Because AdaptableStorage lets the mappers choose their own persistence
boundaries, some objects that inherit from Persistent may be unknown
to ZODB, even though they are in the database.  I call these unmanaged
persistent objects.

The problem with unmanaged persistent objects surfaces when you change
them without changing their container.  For example, if you add an
item to a BTree, the BTree object (which is managed) does not get
changed, but rather a contained Bucket object (which is often
unmanaged).  We really need the BTree to be notified when the Buckets

To solve this, certain aspect serializers (currently only
RemainderSerializer) now detect unmanaged persistent objects and addq
them to a list.  ZODB looks over this list and assigns them a one-off
"_p_jar" with a register() method.  This special register() method
just sets the _p_changed attribute of the managed object, notifying
ZODB that it must be saved.

I think this is the best solution, even though it's awfully complex to
explain.  The change involved moving the RemainingState aspect to the
"zodb" subpackage, since it already depended on the particulars of the
Persistent base class anyway.  It also required changing
ObjectSerializer so that the event object gets constructed by the
caller, which is appropriate, I think.

Also made some minor changes.

=== Products/AdaptableStorage/serial/interfaces/IAspectEvent.py 1.1 => 1.2 ===
--- Products/AdaptableStorage/serial/interfaces/IAspectEvent.py:1.1	Mon Dec  9 13:25:28 2002
+++ Products/AdaptableStorage/serial/interfaces/IAspectEvent.py	Fri Dec 13 15:42:02 2002
@@ -32,3 +32,16 @@
     def getAspectName():
         """Returns the name of the aspect being (de)serialized."""
+    def addUnmanagedPersistentObjects(obs):
+        """Notifies that there are unmanaged persistent objects in the object.
+        If no attention is paid to unmanaged persistent objects, they
+        will not notify ZODB when they are changed, and hence can be a
+        challenge for the application programmer.  Use this method to
+        tell ZODB about the unmanaged persistent objects so that ZODB
+        can deal with them specially.
+        """
+    def getUnmanagedPersistentObjects():
+        """Returns the list of unmanaged persistent objects."""

=== Products/AdaptableStorage/serial/interfaces/IFullDeserializationEvent.py 1.1 => 1.2 ===
--- Products/AdaptableStorage/serial/interfaces/IFullDeserializationEvent.py:1.1	Wed Nov 27 13:37:06 2002
+++ Products/AdaptableStorage/serial/interfaces/IFullDeserializationEvent.py	Fri Dec 13 15:42:02 2002
@@ -23,6 +23,7 @@
     """Deserialization event with features for deserializing internal refs
-    def loadInternalReference(ref):
+    def loadInternalRef(ref):
         """Returns an object for a reference of the form (aspect_name, name).

=== Products/AdaptableStorage/serial/interfaces/IFullSerializationEvent.py 1.1 => 1.2 ===
--- Products/AdaptableStorage/serial/interfaces/IFullSerializationEvent.py:1.1	Wed Nov 27 13:37:06 2002
+++ Products/AdaptableStorage/serial/interfaces/IFullSerializationEvent.py	Fri Dec 13 15:42:02 2002
@@ -26,6 +26,6 @@
     def getSerializedAttributeNames():
         """Returns the name of all attributes serialized."""
-    def getInternalReference(ob):
+    def getInternalRef(ob):
         """Returns (aspect_name, name) or None."""

=== Products/AdaptableStorage/serial/interfaces/IObjectSerializer.py 1.4 => 1.5 ===
--- Products/AdaptableStorage/serial/interfaces/IObjectSerializer.py:1.4	Mon Dec  9 13:25:28 2002
+++ Products/AdaptableStorage/serial/interfaces/IObjectSerializer.py	Fri Dec 13 15:42:02 2002
@@ -34,7 +34,7 @@
         """Returns true if this mapper can serialize the given object.
-    def serialize(keyed_ob_sys, object_mapper, keychain, object):
+    def serialize(object, event):
         """Returns the serialization of an object.
         Returns a pair containing the serialized state of the object
@@ -44,7 +44,7 @@
         corresponding aspects.
-    def deserialize(keyed_ob_sys, object_mapper, keychain, object, full_state):
+    def deserialize(object, event, full_state):
         """Fills an object based on a previously serialized state.