SVN: ZODB/trunk/src/ZEO/ClientStorage.py Fixed bug:

Jim Fulton <[email protected]>
Newsgroups gmane.comp.python.zope.zodb.cvs
Message-ID <[email protected]>
Log message for revision 103173:
  Fixed bug:
    When committing transactions involving blobs to ClientStorages with
    non-shared blob directories, a failure could occur in tpc_finish if
    there was insufficient disk space to copy the blob file or if the
    file wasn't available.  https://bugs.launchpad.net/zodb/+bug/224169
  
  Now link/copy file when storeBlob is called.
  

Changed:
  U   ZODB/trunk/src/ZEO/ClientStorage.py

-=-
Modified: ZODB/trunk/src/ZEO/ClientStorage.py
===================================================================
--- ZODB/trunk/src/ZEO/ClientStorage.py	2009-08-24 16:55:34 UTC (rev 103172)
+++ ZODB/trunk/src/ZEO/ClientStorage.py	2009-08-24 18:17:51 UTC (rev 103173)
@@ -918,34 +918,30 @@
     def storeBlob(self, oid, serial, data, blobfilename, version, txn):
         """Storage API: store a blob object."""
         assert not version
-        serials = self.store(oid, serial, data, '', txn)
-        if self.shared_blob_dir:
-            self._storeBlob_shared(oid, serial, data, blobfilename, txn)
-        else:
-            self._server.storeBlob(oid, serial, data, blobfilename, txn)
-            self._tbuf.storeBlob(oid, blobfilename)
-        return serials
 
-    def _storeBlob_shared(self, oid, serial, data, filename, txn):
-        # First, move the blob into the blob directory
+        # Grab the file right away. That way, if we don't have enough
+        # room for a copy, we'll know now rather than in tpc_finish.
+        # Also, this releaves the client of having to manage the file
+        # (or the directory contianing it).
         self.fshelper.getPathForOID(oid, create=True)
         fd, target = self.fshelper.blob_mkstemp(oid, serial)
         os.close(fd)
 
-        if sys.platform == 'win32':
-            # On windows, we can't rename to an existing file.  We'll
-            # use a slightly different file name. We keep the old one
-            # until we're done to avoid conflicts. Then remove the old name.
-            target += 'w'
-            ZODB.blob.rename_or_copy_blob(filename, target)
-            os.remove(target[:-1])
+        # It's a bit odd (and impossible on windows) to rename over
+        # an existing file.  We'll use the temporary file name as a base.
+        target += '-'
+        ZODB.blob.rename_or_copy_blob(blobfilename, target)
+        os.remove(target[:-1])
+
+        serials = self.store(oid, serial, data, '', txn)
+        if self.shared_blob_dir:
+            self._server.storeBlobShared(
+                oid, serial, data, os.path.basename(target), id(txn))
         else:
-            ZODB.blob.rename_or_copy_blob(filename, target)
+            self._server.storeBlob(oid, serial, data, target, txn)
+            self._tbuf.storeBlob(oid, target)
+        return serials
 
-        # Now tell the server where we put it
-        self._server.storeBlobShared(
-            oid, serial, data, os.path.basename(target), id(txn))
-
     def receiveBlobStart(self, oid, serial):
         blob_filename = self.fshelper.getBlobFilename(oid, serial)
         assert not os.path.exists(blob_filename)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.