[Zodb-checkins] SVN: ZODB/trunk/src/ZEO/ClientStorage.py Fixed bug:
Jim Fulton
jim at zope.com
Mon Aug 24 14:17:51 EDT 2009
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)
More information about the Zodb-checkins
mailing list