[Zodb-checkins] CVS: ZEO/ZEO - ClientCache.py:1.18.6.3.2.1 ClientStorage.py:1.35.6.4.2.1 ClientStub.py:1.3.2.2.2.1 Exceptions.py:1.3.2.1.2.1 ServerStub.py:1.3.2.1.2.1 StorageServer.py:1.32.6.3.2.1 TransactionBuffer.py:1.3.2.2.2.1 __init__.py:1.7.6.1.2.1 asyncwrap.py:1.2.4.1.2.1 fap.py:1.5.6.1.2.1 smac.py:1.11.4.4.2.1 start.py:1.26.4.2.2.1 trigger.py:1.3.4.2.2.1 Invalidator.py:NONE zrpc.py:NONE

Jeremy Hylton jeremy@zope.com
Thu, 25 Apr 2002 16:20:25 -0400


Update of /cvs-repository/ZEO/ZEO
In directory cvs.zope.org:/tmp/cvs-serv5401/ZEO

Modified Files:
      Tag: ZEO2-branch
	ClientCache.py ClientStorage.py ClientStub.py Exceptions.py 
	ServerStub.py StorageServer.py TransactionBuffer.py 
	__init__.py asyncwrap.py fap.py smac.py start.py trigger.py 
Removed Files:
      Tag: ZEO2-branch
	Invalidator.py zrpc.py 
Log Message:
Merge the Standby-branch into the ZEO2-branch.

The Standby-branch is history.



=== ZEO/ZEO/ClientCache.py 1.18.6.3 => 1.18.6.3.2.1 === (432/532 lines abridged)
-# 
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-# 
-# Copyright (c) Digital Creations.  All rights reserved.
-# 
-# This license has been certified as Open Source(tm).
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-# 1. Redistributions in source code must retain the above copyright
-#    notice, this list of conditions, and the following disclaimer.
-# 
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions, and the following disclaimer in
-#    the documentation and/or other materials provided with the
-#    distribution.
-# 
-# 3. Digital Creations requests that attribution be given to Zope
-#    in any manner possible. Zope includes a "Powered by Zope"
-#    button that is installed by default. While it is not a license
-#    violation to remove this button, it is requested that the
-#    attribution remain. A significant investment has been put
-#    into Zope, and this effort will continue if the Zope community
-#    continues to grow. This is one way to assure that growth.
-# 
-# 4. All advertising materials and documentation mentioning
-#    features derived from or use of this software must display
-#    the following acknowledgement:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    In the event that the product being advertised includes an
-#    intact Zope distribution (with copyright and license included)
-#    then this clause is waived.
-# 
-# 5. Names associated with Zope or Digital Creations must not be used to
-#    endorse or promote products derived from this software without
-#    prior written permission from Digital Creations.
-# 
-# 6. Modified redistributions of any form whatsoever must retain
-#    the following acknowledgment:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."

[-=- -=- -=- 432 lines omitted -=- -=- -=-]

-            if len(vdlen) != 4: break
-            vdlen=unpack(">i", vdlen)[0]
-            if vlen+dlen+42+vdlen > tlen: break
+            vdlen = read(4)
+            if len(vdlen) != 4:
+                break
+            vdlen = unpack(">i", vdlen)[0]
+            if vlen+dlen+42+vdlen > tlen:
+                break
             seek(vdlen, 1)
-            vs=read(8)
-            if read(4) != h[9:13]: break
-        else: vs=None
+            vs = read(8)
+            if read(4) != h[9:13]:
+                break
+        else:
+            vs = None
 
         if h[8] in 'vn':
-            if current: index[oid]=-pos
-            else: index[oid]=pos
-            serial[oid]=h[-8:], vs
+            if current:
+                index[oid] = -pos
+            else:
+                index[oid] = pos
+            serial[oid] = h[-8:], vs
         else:
             if serial.has_key(oid):
                 # We have a record for this oid, but it was invalidated!
                 del serial[oid]
                 del index[oid]
-            
-            
-        pos=pos+tlen
+
+
+        pos = pos + tlen
 
     f.seek(pos)
-    try: f.truncate()
-    except: pass
-    
+    try:
+        f.truncate()
+    except:
+        pass
+
     return pos


=== ZEO/ZEO/ClientStorage.py 1.35.6.4 => 1.35.6.4.2.1 ===
-# 
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-# 
-# Copyright (c) Digital Creations.  All rights reserved.
-# 
-# This license has been certified as Open Source(tm).
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-# 1. Redistributions in source code must retain the above copyright
-#    notice, this list of conditions, and the following disclaimer.
-# 
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions, and the following disclaimer in
-#    the documentation and/or other materials provided with the
-#    distribution.
-# 
-# 3. Digital Creations requests that attribution be given to Zope
-#    in any manner possible. Zope includes a "Powered by Zope"
-#    button that is installed by default. While it is not a license
-#    violation to remove this button, it is requested that the
-#    attribution remain. A significant investment has been put
-#    into Zope, and this effort will continue if the Zope community
-#    continues to grow. This is one way to assure that growth.
-# 
-# 4. All advertising materials and documentation mentioning
-#    features derived from or use of this software must display
-#    the following acknowledgement:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    In the event that the product being advertised includes an
-#    intact Zope distribution (with copyright and license included)
-#    then this clause is waived.
-# 
-# 5. Names associated with Zope or Digital Creations must not be used to
-#    endorse or promote products derived from this software without
-#    prior written permission from Digital Creations.
-# 
-# 6. Modified redistributions of any form whatsoever must retain
-#    the following acknowledgment:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    Intact (re-)distributions of any official Zope release do not
-#    require an external acknowledgement.
-# 
-# 7. Modifications are encouraged but must be packaged separately as
-#    patches to official Zope releases.  Distributions that do not
-#    clearly separate the patches from the original work must be clearly
-#    labeled as unofficial distributions.  Modifications which do not
-#    carry the name Zope may be packaged in any form, as long as they
-#    conform to all of the clauses above.
-# 
-# 
-# Disclaimer
-# 
-#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-#   SUCH DAMAGE.
-# 
-# 
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations.  Specific
-# attributions are listed in the accompanying credits file.
+#
+# Copyright (c) 2001, 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
 # 
 ##############################################################################
 """Network ZODB storage client
@@ -192,7 +121,7 @@
 
         # Prevent multiple new_oid calls from going out.  The _oids
         # variable should only be modified while holding the
-        # oid_cond. 
+        # oid_cond.
         self.oid_cond = threading.Condition()
 
         commit_lock = threading.Lock()
@@ -204,10 +133,12 @@
         self._oid='\0\0\0\0\0\0\0\0'
 
     def close(self):
-        self._rpc_mgr.close()
+        if self._tbuf is not None:
+            self._tbuf.close()
         if self._cache is not None:
             self._cache.close()
-        
+        self._rpc_mgr.close()
+
     def registerDB(self, db, limit):
         """Register that the storage is controlled by the given DB."""
         log2(INFO, "registerDB(%s, %s)" % (repr(db), repr(limit)))
@@ -220,7 +151,7 @@
             return 1
 
     def notifyConnected(self, c):
-        log2(INFO, "Connected to storage")
+        log2(INFO, "Connected to storage via %s" % repr(c))
         stub = ServerStub.StorageServer(c)
 
         self._oids = []
@@ -228,6 +159,7 @@
         # XXX Why is this synchronous?  If it were async, verification
         # would start faster.
         stub.register(str(self._storage), self._is_read_only)
+        self._info.update(stub.get_info())
         self.verify_cache(stub)
 
         # Don't make the server available to clients until after
@@ -263,10 +195,10 @@
 
     def getSize(self):
         return self._info['size']
-                  
+
     def supportsUndo(self):
         return self._info['supportsUndo']
-    
+
     def supportsVersions(self):
         return self._info['supportsVersions']
 
@@ -286,7 +218,7 @@
             else:
                 raise exc(self._transaction, trans)
         return 1
-        
+
     def _check_tid(self, tid, exc=None):
         if self.tpc_tid != tid:
             if exc is None:
@@ -305,11 +237,6 @@
             self._tbuf.invalidate(oid, src)
         return oids
 
-    def close(self):
-        self._rpc_mgr.close()
-        if self._cache is not None:
-            self._cache.close()
-        
     def commitVersion(self, src, dest, transaction):
         if self._is_read_only:
             raise POSException.ReadOnlyError()
@@ -327,10 +254,10 @@
         return oids
 
     def history(self, oid, version, length=1):
-        return self._server.history(oid, version, length)     
-                  
+        return self._server.history(oid, version, length)
+
     def loadSerial(self, oid, serial):
-        return self._server.loadSerial(oid, serial)     
+        return self._server.loadSerial(oid, serial)
 
     def load(self, oid, version, _stuff=None):
         p = self._cache.load(oid, version)
@@ -347,7 +274,7 @@
             if s:
                 return p, s
             raise KeyError, oid # no non-version data for this
-                    
+
     def modifiedInVersion(self, oid):
         v = self._cache.modifiedInVersion(oid)
         if v is not None:
@@ -366,7 +293,7 @@
         oid = self._oids.pop()
         self.oid_cond.release()
         return oid
-        
+
     def pack(self, t=None, rf=None, wait=0, days=0):
         if self._is_read_only:
             raise POSException.ReadOnlyError()
@@ -391,7 +318,7 @@
         if self._is_read_only:
             raise POSException.ReadOnlyError()
         self._check_trans(transaction, POSException.StorageTransactionError)
-        self._server.storea(oid, serial, data, version, self._serial) 
+        self._server.storea(oid, serial, data, version, self._serial)
         self._tbuf.store(oid, version, data)
         return self._check_serials()
 
@@ -400,7 +327,7 @@
             return
         self._server.vote(self._serial)
         return self._check_serials()
-            
+
     def tpc_abort(self, transaction):
         if transaction is not self._transaction:
             return
@@ -412,7 +339,7 @@
         self.tpc_cond.notify()
         self.tpc_cond.release()
 
-    def tpc_begin(self, transaction):
+    def tpc_begin(self, transaction, tid=None, status=' '):
         self.tpc_cond.acquire()
         while self._transaction is not None:
             if self._transaction == transaction:
@@ -423,7 +350,7 @@
         if self._server is None:
             self.tpc_cond.release()
             raise ClientDisconnected()
-            
+
         self._ts = get_timestamp(self._ts)
         id = `self._ts`
         self._transaction = transaction
@@ -432,7 +359,8 @@
             r = self._server.tpc_begin(id,
                                        transaction.user,
                                        transaction.description,
-                                       transaction._extension)
+                                       transaction._extension,
+                                       tid, status)
         except:
             # Client may have disconnected during the tpc_begin().
             # Then notifyDisconnected() will have released the lock.
@@ -463,7 +391,7 @@
 
     def _update_cache(self):
         # Iterate over the objects in the transaction buffer and
-        # update or invalidate the cache. 
+        # update or invalidate the cache.
         self._cache.checkSize(self._tbuf.get_size())
         self._tbuf.begin_iterate()
         while 1:
@@ -476,7 +404,7 @@
             if t is None:
                 break
             oid, v, p = t
-            if p is None: # an invalidation 
+            if p is None: # an invalidation
                 s = None
             else:
                 s = self._seriald[oid]
@@ -501,7 +429,7 @@
         # XXX what are the sync issues here?
         oids = self._server.undo(transaction_id)
         for oid in oids:
-            self._cache.invalidate(oid, '')                
+            self._cache.invalidate(oid, '')
         return oids
 
     def undoInfo(self, first=0, last=-20, specification=None):
@@ -510,7 +438,7 @@
     def undoLog(self, first, last, filter=None):
         if filter is not None:
             return () # can't pass a filter to server
-        
+
         return self._server.undoLog(first, last) # Eek!
 
     def versionEmpty(self, version):
@@ -528,7 +456,7 @@
         self._info.update(dict)
 
     def begin(self):
-        self._tfile = tempfile.TemporaryFile()
+        self._tfile = tempfile.TemporaryFile(suffix=".inv")
         self._pickler = cPickle.Pickler(self._tfile, 1)
         self._pickler.fast = 1 # Don't use the memo
 
@@ -544,6 +472,7 @@
         self._pickler.dump((0,0))
         self._tfile.seek(0)
         unpick = cPickle.Unpickler(self._tfile)
+        f = self._tfile
         self._tfile = None
 
         while 1:
@@ -552,6 +481,7 @@
                 break
             self._cache.invalidate(oid, version=version)
             self._db.invalidate(oid, version=version)
+        f.close()
 
     def Invalidate(self, args):
         for oid, version in args:


=== ZEO/ZEO/ClientStub.py 1.3.2.2 => 1.3.2.2.2.1 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
 """Stub for interface exported by ClientStorage"""
 
 class ClientStorage:
     def __init__(self, rpc):
         self.rpc = rpc
-        
+
     def beginVerify(self):
         self.rpc.callAsync('begin')
 


=== ZEO/ZEO/Exceptions.py 1.3.2.1 => 1.3.2.1.2.1 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
 """Exceptions for ZEO."""
 
 class Disconnected(Exception):


=== ZEO/ZEO/ServerStub.py 1.3.2.1 => 1.3.2.1.2.1 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
 """Stub for interface exposed by StorageServer"""
 
 class StorageServer:
@@ -28,7 +41,7 @@
             return self.rpc.call('new_oids')
         else:
             return self.rpc.call('new_oids', n)
-            
+
     def pack(self, t, wait=None):
         if wait is None:
             self.rpc.call('pack', t)
@@ -41,8 +54,8 @@
     def storea(self, oid, serial, data, version, id):
         self.rpc.callAsync('storea', oid, serial, data, version, id)
 
-    def tpc_begin(self, id, user, descr, ext):
-        return self.rpc.call('tpc_begin', id, user, descr, ext)
+    def tpc_begin(self, id, user, descr, ext, tid, status):
+        return self.rpc.call('tpc_begin', id, user, descr, ext, tid, status)
 
     def vote(self, trans_id):
         return self.rpc.call('vote', trans_id)
@@ -58,7 +71,7 @@
 
     def commitVersion(self, src, dest, id):
         return self.rpc.call('commitVersion', src, dest, id)
-        
+
     def history(self, oid, version, length=None):
         if length is not None:
             return self.rpc.call('history', oid, version)
@@ -104,5 +117,3 @@
             return self.rpc.call('versions')
         else:
             return self.rpc.call('versions', max)
-
-    


=== ZEO/ZEO/StorageServer.py 1.32.6.3 => 1.32.6.3.2.1 ===
-# 
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-# 
-# Copyright (c) Digital Creations.  All rights reserved.
-# 
-# This license has been certified as Open Source(tm).
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-# 1. Redistributions in source code must retain the above copyright
-#    notice, this list of conditions, and the following disclaimer.
-# 
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions, and the following disclaimer in
-#    the documentation and/or other materials provided with the
-#    distribution.
-# 
-# 3. Digital Creations requests that attribution be given to Zope
-#    in any manner possible. Zope includes a "Powered by Zope"
-#    button that is installed by default. While it is not a license
-#    violation to remove this button, it is requested that the
-#    attribution remain. A significant investment has been put
-#    into Zope, and this effort will continue if the Zope community
-#    continues to grow. This is one way to assure that growth.
-# 
-# 4. All advertising materials and documentation mentioning
-#    features derived from or use of this software must display
-#    the following acknowledgement:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    In the event that the product being advertised includes an
-#    intact Zope distribution (with copyright and license included)
-#    then this clause is waived.
-# 
-# 5. Names associated with Zope or Digital Creations must not be used to
-#    endorse or promote products derived from this software without
-#    prior written permission from Digital Creations.
-# 
-# 6. Modified redistributions of any form whatsoever must retain
-#    the following acknowledgment:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    Intact (re-)distributions of any official Zope release do not
-#    require an external acknowledgement.
-# 
-# 7. Modifications are encouraged but must be packaged separately as
-#    patches to official Zope releases.  Distributions that do not
-#    clearly separate the patches from the original work must be clearly
-#    labeled as unofficial distributions.  Modifications which do not
-#    carry the name Zope may be packaged in any form, as long as they
-#    conform to all of the clauses above.
 #
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
 # 
-# Disclaimer
-# 
-#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-#   SUCH DAMAGE.
-# 
-# 
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations.  Specific
-# attributions are listed in the accompanying credits file.
+# 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
 # 
 ##############################################################################
 """Network ZODB storage server
@@ -135,7 +64,7 @@
         c = ManagedServerConnection(sock, addr, ZEOStorage(self), self)
         log("new connection %s: %s" % (addr, `c`))
         return c
-        
+
     def register(self, storage_id, proxy):
         """Register a connection's use with a particular storage.
 
@@ -150,7 +79,7 @@
         l.append(proxy)
 
     def invalidate(self, conn, storage_id, invalidated=(), info=0):
-        for p in self.connections[storage_id]:
+        for p in self.connections.get(storage_id, ()):
             if invalidated and p is not conn:
                 p.client.Invalidate(invalidated)
             else:
@@ -188,7 +117,7 @@
 
     def notifyConnected(self, conn):
         self.client = ClientStub.ClientStorage(conn)
-        
+
     def __repr__(self):
         tid = self._transaction and repr(self._transaction.id)
         if self.__storage:
@@ -196,8 +125,8 @@
                    repr(self.__storage._transaction.id)
         else:
             stid = None
-        return "<StorageProxy %X trans=%s s_trans=%s>" % (id(self), tid,
-                                                          stid)
+        name = self.__class__.__name__
+        return "<%s %X trans=%s s_trans=%s>" % (name, id(self), tid, stid)
 
     def _log(self, msg, level=zLOG.INFO, error=None, pid=os.getpid()):
         zLOG.LOG("ZEO Server:%s:%s" % (pid, self.__storage_id),
@@ -303,11 +232,11 @@
         t.start()
 
     def _pack(self, t, wait=0):
-        try: 
+        try:
             self.__storage.pack(t, referencesf)
         except:
-            self._log('ZEO Server', zLOG.ERROR,
-                      'Pack failed for %s' % self.__storage_id,
+            self._log('Pack failed for %s' % self.__storage_id,
+                      zLOG.ERROR,
                       error=sys.exc_info())
             if wait:
                 raise
@@ -379,8 +308,11 @@
 
     def transactionalUndo(self, trans_id, id):
         self._check_tid(id, exc=StorageTransactionError)
-        return self.__storage.transactionalUndo(trans_id, self._transaction)
-        
+        oids = self.__storage.transactionalUndo(trans_id, self._transaction)
+        for oid in oids:
+            self.__invalidated.append((oid, None))
+        return oids
+
     def undo(self, transaction_id):
         oids = self.__storage.undo(transaction_id)
         if oids:
@@ -401,7 +333,7 @@
     # be the same.)  The new transaction's proxy sets its _transaction
     # and continues from there.
 
-    def tpc_begin(self, id, user, description, ext):
+    def tpc_begin(self, id, user, description, ext, tid, status):
         if self._transaction is not None:
             if self._transaction.id == id:
                 self._log("duplicate tpc_begin(%s)" % repr(id))
@@ -418,11 +350,11 @@
 
         if self.__storage._transaction is not None:
             d = Delay()
-            self.__storage.__waiting.append((d, self, t))
+            self.__storage.__waiting.append((d, self, t, tid, status))
             return d
 
         self._transaction = t
-        self.__storage.tpc_begin(t)
+        self.__storage.tpc_begin(t, tid, status)
         self.__invalidated = []
 
     def tpc_finish(self, id):
@@ -451,20 +383,20 @@
             self._transaction = None
             self.__invalidated = []
 
-    def _restart_delayed_transaction(self, delay, trans):
+    def _restart_delayed_transaction(self, delay, trans, tid, status):
         self._transaction = trans
-        self.__storage.tpc_begin(trans)
+        self.__storage.tpc_begin(trans, tid, status)
         self.__invalidated = []
         assert self._transaction.id == self.__storage._transaction.id
         delay.reply(None)
 
     def _handle_waiting(self):
         if self.__storage.__waiting:
-            delay, proxy, trans = self.__storage.__waiting.pop(0)
-            proxy._restart_delayed_transaction(delay, trans)
+            delay, proxy, trans, tid, status = self.__storage.__waiting.pop(0)
+            proxy._restart_delayed_transaction(delay, trans, tid, status)
             if self is proxy:
                 return 1
-        
+
     def new_oids(self, n=100):
         """Return a sequence of n new oids, where n defaults to 100"""
         if n < 0:


=== ZEO/ZEO/TransactionBuffer.py 1.3.2.2 => 1.3.2.2.2.1 ===
+#
+# Copyright (c) 2001, 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
+# 
+##############################################################################
 """A TransactionBuffer store transaction updates until commit or abort.
 
 A transaction may generate enough data that it is not practical to
@@ -12,9 +25,9 @@
 import cPickle
 
 class TransactionBuffer:
-    
+
     def __init__(self):
-        self.file = tempfile.TemporaryFile()
+        self.file = tempfile.TemporaryFile(suffix=".tbuf")
         self.count = 0
         self.size = 0
         # It's safe to use a fast pickler because the only objects
@@ -22,6 +35,9 @@
         self.pickler = cPickle.Pickler(self.file, 1)
         self.pickler.fast = 1
 
+    def close(self):
+        self.file.close()
+
     def store(self, oid, version, data):
         """Store oid, version, data for later retrieval"""
         self.pickler.dump((oid, version, data))
@@ -59,8 +75,8 @@
         oid_ver_data = self.unpickler.load()
         self.count -= 1
         return oid_ver_data
-            
+
     def get_size(self):
         """Return size of data stored in buffer (just a hint)."""
-    
+
         return self.size


=== ZEO/ZEO/__init__.py 1.7.6.1 => 1.7.6.1.2.1 ===
+##############################################################################
 #
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (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.
-
-
+# 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
+# 
+##############################################################################
 import fap


=== ZEO/ZEO/asyncwrap.py 1.2.4.1 => 1.2.4.1.2.1 ===
+##############################################################################
 #
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (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.
-
+# 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
+# 
+##############################################################################
 """A wrapper for asyncore that provides robust exception handling.
 
 The poll() and loop() calls exported by asyncore can raise exceptions.
@@ -40,7 +44,7 @@
                 raise
         else:
             break
-    
+
 def poll(*args, **kwargs):
     try:
         apply(asyncore.poll, args, kwargs)


=== ZEO/ZEO/fap.py 1.5.6.1 => 1.5.6.1.2.1 ===
+##############################################################################
 #
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (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.
-
-
+# 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
+# 
+##############################################################################
 """ZEO depends on recent versions of asyncore and cPickle
 
 Try to fix up the imports of these to make these dependencies work,
@@ -21,7 +24,7 @@
     try: m=imp.find_module('ZServer', [where])
     except: return 0
     else: return 1
-    
+
 
 def fap():
     # if we are using an old version of Python, our asyncore is likely to
@@ -33,12 +36,12 @@
     except:
         # Try a little harder to import ZServer
         import os, imp
-        
+
         location = package_home()
         location = os.path.split(location)[0]
         location = os.path.split(location)[0]
         location = os.path.split(location)[0]
-        
+
         if whiff(location):
             sys.path.append(location)
             try:


=== ZEO/ZEO/smac.py 1.11.4.4 => 1.11.4.4.2.1 ===
-# 
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-# 
-# Copyright (c) Digital Creations.  All rights reserved.
-# 
-# This license has been certified as Open Source(tm).
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-# 1. Redistributions in source code must retain the above copyright
-#    notice, this list of conditions, and the following disclaimer.
-# 
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions, and the following disclaimer in
-#    the documentation and/or other materials provided with the
-#    distribution.
-# 
-# 3. Digital Creations requests that attribution be given to Zope
-#    in any manner possible. Zope includes a "Powered by Zope"
-#    button that is installed by default. While it is not a license
-#    violation to remove this button, it is requested that the
-#    attribution remain. A significant investment has been put
-#    into Zope, and this effort will continue if the Zope community
-#    continues to grow. This is one way to assure that growth.
-# 
-# 4. All advertising materials and documentation mentioning
-#    features derived from or use of this software must display
-#    the following acknowledgement:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    In the event that the product being advertised includes an
-#    intact Zope distribution (with copyright and license included)
-#    then this clause is waived.
-# 
-# 5. Names associated with Zope or Digital Creations must not be used to
-#    endorse or promote products derived from this software without
-#    prior written permission from Digital Creations.
-# 
-# 6. Modified redistributions of any form whatsoever must retain
-#    the following acknowledgment:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    Intact (re-)distributions of any official Zope release do not
-#    require an external acknowledgement.
-# 
-# 7. Modifications are encouraged but must be packaged separately as
-#    patches to official Zope releases.  Distributions that do not
-#    clearly separate the patches from the original work must be clearly
-#    labeled as unofficial distributions.  Modifications which do not
-#    carry the name Zope may be packaged in any form, as long as they
-#    conform to all of the clauses above.
-# 
-# 
-# Disclaimer
-# 
-#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-#   SUCH DAMAGE.
-# 
-# 
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations.  Specific
-# attributions are listed in the accompanying credits file.
+#
+# Copyright (c) 2001, 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
 # 
 ##############################################################################
 """Sized message async connections
@@ -198,7 +127,7 @@
 
     def readable(self):
         return 1
-    
+
     def writable(self):
         if len(self.__output) == 0:
             return 0


=== ZEO/ZEO/start.py 1.26.4.2 => 1.26.4.2.2.1 ===
-# 
-# Zope Public License (ZPL) Version 1.0
-# -------------------------------------
-# 
-# Copyright (c) Digital Creations.  All rights reserved.
-# 
-# This license has been certified as Open Source(tm).
-# 
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-# 
-# 1. Redistributions in source code must retain the above copyright
-#    notice, this list of conditions, and the following disclaimer.
-# 
-# 2. Redistributions in binary form must reproduce the above copyright
-#    notice, this list of conditions, and the following disclaimer in
-#    the documentation and/or other materials provided with the
-#    distribution.
-# 
-# 3. Digital Creations requests that attribution be given to Zope
-#    in any manner possible. Zope includes a "Powered by Zope"
-#    button that is installed by default. While it is not a license
-#    violation to remove this button, it is requested that the
-#    attribution remain. A significant investment has been put
-#    into Zope, and this effort will continue if the Zope community
-#    continues to grow. This is one way to assure that growth.
-# 
-# 4. All advertising materials and documentation mentioning
-#    features derived from or use of this software must display
-#    the following acknowledgement:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    In the event that the product being advertised includes an
-#    intact Zope distribution (with copyright and license included)
-#    then this clause is waived.
-# 
-# 5. Names associated with Zope or Digital Creations must not be used to
-#    endorse or promote products derived from this software without
-#    prior written permission from Digital Creations.
-# 
-# 6. Modified redistributions of any form whatsoever must retain
-#    the following acknowledgment:
-# 
-#      "This product includes software developed by Digital Creations
-#      for use in the Z Object Publishing Environment
-#      (http://www.zope.org/)."
-# 
-#    Intact (re-)distributions of any official Zope release do not
-#    require an external acknowledgement.
-# 
-# 7. Modifications are encouraged but must be packaged separately as
-#    patches to official Zope releases.  Distributions that do not
-#    clearly separate the patches from the original work must be clearly
-#    labeled as unofficial distributions.  Modifications which do not
-#    carry the name Zope may be packaged in any form, as long as they
-#    conform to all of the clauses above.
-# 
-# 
-# Disclaimer
-# 
-#   THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS ``AS IS'' AND ANY
-#   EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-#   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-#   PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL DIGITAL CREATIONS OR ITS
-#   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
-#   USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-#   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-#   OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
-#   OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-#   SUCH DAMAGE.
-# 
-# 
-# This software consists of contributions made by Digital Creations and
-# many individuals on behalf of Digital Creations.  Specific
-# attributions are listed in the accompanying credits file.
+#
+# Copyright (c) 2001, 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
 # 
 ##############################################################################
-
 """Start the server storage.
 """
 
@@ -99,7 +27,7 @@
         d=os.path.split(d)[0]
         if not d or d=='.': d=os.getcwd()
         n=n-1
-        
+
     return d
 
 def get_storage(m, n, cache={}):
@@ -150,7 +78,7 @@
        -D -- Run in debug mode
 
        -U -- Unix-domain socket file to listen on
-    
+
        -u username or uid number
 
          The username to run the ZEO server as. You may want to run
@@ -191,7 +119,7 @@
         print usage
         print msg
         sys.exit(1)
-    
+
     port=None
     debug=0
     host=''
@@ -234,7 +162,7 @@
     from zLOG import LOG, INFO, ERROR
 
     # Try to set uid to "-u" -provided uid.
-    # Try to set gid to  "-u" user's primary group. 
+    # Try to set gid to  "-u" user's primary group.
     # This will only work if this script is run by root.
     try:
         import pwd
@@ -249,7 +177,7 @@
                 uid = pwd.getpwuid(UID)[2]
                 gid = pwd.getpwuid(UID)[3]
             else:
-                raise KeyError 
+                raise KeyError
             try:
                 if gid is not None:
                     try:
@@ -355,7 +283,7 @@
             "Shutting down (%s)" % (die and "shutdown" or "restart")
             )
     except: pass
-    
+
     if die: sys.exit(0)
     else: sys.exit(1)
 


=== ZEO/ZEO/trigger.py 1.3.4.2 => 1.3.4.2.2.1 ===
+##############################################################################
 #
+# Copyright (c) 2001, 2002 Zope Corporation and Contributors.
+# All Rights Reserved.
+# 
 # This software is subject to the provisions of the Zope Public License,
-# Version 1.1 (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.
-
-# This module is a simplified version of the select_trigger module
-# from Sam Rushing's Medusa server.
-
+# 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
+# 
+##############################################################################
 import asyncore
 
 import os
 import socket
 import string
 import thread
-    
+
 if os.name == 'posix':
 
     class trigger (asyncore.file_dispatcher):
@@ -138,7 +139,7 @@
                     if port <= 19950:
                         raise 'Bind Error', 'Cannot bind trigger!'
                     port=port - 1
-            
+
             a.listen (1)
             w.setblocking (0)
             try:

=== Removed File ZEO/ZEO/Invalidator.py ===

=== Removed File ZEO/ZEO/zrpc.py ===