[Zope-CVS] CVS: Products/AdaptableStorage/zodb - public.py:1.1 ASConnection.py:1.2 ASStorage.py:1.2

Shane Hathaway shane@zope.com
Tue, 3 Dec 2002 18:10:56 -0500


Update of /cvs-repository/Products/AdaptableStorage/zodb
In directory cvs.zope.org:/tmp/cvs-serv22143/zodb

Modified Files:
	ASConnection.py ASStorage.py 
Added Files:
	public.py 
Log Message:
Running AdaptableStorage with the latest Zope revealed some flaws.
Fixed them all.

- Consistent ordering of transaction participants now makes it impossible to
  add a jar to the transaction after the commit() method has begun.
  AdaptableStorage (and perhaps other projects like ZPatterns) relied on
  the ability to add a jar after commit has started.  This could lead to
  a deadlock.  Reworked ASStorage, FSConnection, and the tests to deal with
  this.

- Serials are now required to be hashable.  This makes serials, used to
  prevent conflicts, simpler and more robust.

- DBTab needs some kind of class it can call directly, so I added
  the small subclasses FSStorage and FSDatabase to Zope2FS.

- Restored the PersistentExtra patch.

- The directory items gateway wants to write data about its children, but
  sometimes its children aren't being written at the same time.  Added
  a "conditional" optional flag to FSConnection.writeSection(), allowing
  data to be written only if other data gets written.


=== Added File Products/AdaptableStorage/zodb/public.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""zodb public names

$Id: public.py,v 1.1 2002/12/03 23:10:55 shane Exp $
"""

from interfaces.public import *
from ASConnection import ASConnection
from ASDB import ASDB
from ASStorage import ASStorage
from OIDEncoder import OIDEncoder
from StaticResource import StaticResource


=== Products/AdaptableStorage/zodb/ASConnection.py 1.1 => 1.2 ===
--- Products/AdaptableStorage/zodb/ASConnection.py:1.1	Wed Nov 27 13:37:08 2002
+++ Products/AdaptableStorage/zodb/ASConnection.py	Tue Dec  3 18:10:55 2002
@@ -24,7 +24,7 @@
 from ZODB.Connection import Connection, StringIO, Unpickler, Pickler, \
      ConflictError, ReadConflictError, ExtensionKlass, LOG, ERROR
 
-from consts import SERIAL0
+from consts import SERIAL0, DEBUG
 from serial_public import IKeyedObjectSystem
 
 
@@ -228,6 +228,8 @@
                 # state=object.__getstate__()
                 mapper, key = self.getOIDInfo(oid)
                 ser = mapper.getSerializer()
+                if DEBUG:
+                    print 'serializing', repr(oid), repr(serial)
                 state, ext_refs = ser.serialize(mapper, key, object, self)
                 if ext_refs:
                     oid_encoder = self._db._oid_encoder
@@ -258,6 +260,7 @@
             # serial number for a newly created object
             try: cache[oid]=object
             except:
+                print 'YIKES!', `object.__dict__`, `cache[oid].__dict__`
                 # Dang, I bet its wrapped:
                 if hasattr(object, 'aq_base'):
                     cache[oid]=object.aq_base
@@ -314,6 +317,8 @@
             #     for k,v in state.items(): d[k]=v
             mapper, key = self.getOIDInfo(oid)
             ser = mapper.getSerializer()
+            if DEBUG:
+                print 'deserializing', repr(oid), repr(serial)
             ser.deserialize(mapper, key, object, self, state)
 
             if mapper.isVolatile():


=== Products/AdaptableStorage/zodb/ASStorage.py 1.1 => 1.2 ===
--- Products/AdaptableStorage/zodb/ASStorage.py:1.1	Wed Nov 27 13:37:08 2002
+++ Products/AdaptableStorage/zodb/ASStorage.py	Tue Dec  3 18:10:55 2002
@@ -28,12 +28,21 @@
 
 class ASStorage(BaseStorage.BaseStorage):
 
-    def __init__(self, domain_resource, oid_encoder=None,
-                 name='AdaptableStorage ZODB backend'):
+    def __init__(self, domain_resource, tpc_conns=(),
+                 oid_encoder=None, name=''):
         self._domain_resource = domain_resource
         if oid_encoder is None:
             oid_encoder = OIDEncoder()
         self._oid_encoder = oid_encoder
+        self._tpc_conns = tpc_conns
+        sort_keys = []
+        names = []
+        for c in tpc_conns:
+            sort_keys.append(c.sortKey())
+            names.append(c.getName())
+        self._sort_key = tuple(sort_keys)
+        if not name:
+            name = 'AdaptableStorage: ' + ', '.join(names)
         BaseStorage.BaseStorage.__init__(self, name)
 
     def __len__(self):
@@ -43,20 +52,16 @@
         # Stub
         return 1
 
-    def hashSerial(self, serial):
-        """Turns any object into an 8-byte checksum.
+    def sortKey(self):
+        return self._sort_key
 
-        Note that this is somewhat inefficient and error-prone if the
-        input includes anything besides simple objects
-        (ints, tuples, strings, etc.)  It seems to work for now.
+    def hashSerial(self, serial):
+        """Returns an 8-byte checksum.
         """
-        s = repr(serial)
-        hash = md5.new(s).digest()[:8]
-        if hash == SERIAL0:  # Avoid the special value.
-            hash = SERIAL1
+        h = '%08x' % hash(serial)
         if DEBUG:
-            print 'hash of %r is %r' % (serial, hash)
-        return hash
+            print 'hash of %r is %r' % (serial, h)
+        return h
 
     def getOIDInfo(self, oid):
         mapper_name, key = self._oid_encoder.decode(oid)
@@ -76,10 +81,10 @@
             p.dump(class_info)
             p.dump(full_state)
             data = file.getvalue()
-            hash = self.hashSerial(serial)
+            h = self.hashSerial(serial)
             if DEBUG:
-                print 'loaded', `oid`, `hash`
-            return data, hash
+                print 'loaded', `oid`, `h`
+            return data, h
         finally:
             self._lock_release()
 
@@ -130,11 +135,21 @@
     def _clear_temp(self):
         pass
 
+    def _abort(self):
+        for c in self._tpc_conns:
+            c.abort()
+
+    def _begin(self, tid, u, d, e):
+        for c in self._tpc_conns:
+            c.begin()
+
     def _finish(self, tid, user, desc, ext):
-        pass
+        for c in self._tpc_conns:
+            c.finish()
 
-    def _abort(self):
-        pass
+    def _vote(self):
+        for c in self._tpc_conns:
+            c.vote()
 
     def pack(self, t, referencesf):
         pass