[RFC][PATCH] ftp transport, dsilver's branch
Matthieu Moy
Matthieu.Moy at imag.fr
Sat Jan 28 21:29:23 GMT 2006
Matthieu Moy <Matthieu.Moy at imag.fr> writes:
> Hi,
>
> First, a reminder: Daniel Silverstone's ftp branch contains some fixes
> that have not been merged. In particular, it allows reusing
> connections instead of creating several ones in parallel[1].
Followup to myself, with another patch:
It tries to solve the problem of ftp server closing the connection
arbitrarily after some time. The patch works for me (I could push a
branch of 849 revisions with 6 temporary failures, but it did it in
one go), but it probably needs to be improved before getting into
upstream. Daniel, I suggest that you merge it into your branch first.
Hopefully, a branch containing this fix will be available here within
a few minutes (I'm going to bed, so let's see if my patch still works
while I'm sleeping):
http://test.bzr.free.fr/branches/bzr.ftp/
The patch (against dsilver's branch) is below:
=== modified file 'bzrlib/transport/ftp.py'
--- bzrlib/transport/ftp.py
+++ bzrlib/transport/ftp.py
@@ -37,7 +37,7 @@
from bzrlib.transport import Transport
from bzrlib.errors import (TransportNotPossible, TransportError,
NoSuchFile, FileExists)
-from bzrlib.trace import mutter
+from bzrlib.trace import mutter, warning
_FTP_cache = {}
@@ -174,7 +174,7 @@
mutter("FTP has not: %s" % self._abspath(relpath))
return False
- def get(self, relpath, decode=False):
+ def get(self, relpath, decode=False, retries=0):
"""Get the file at the given relative path.
:param relpath: The relative path to the file
@@ -190,9 +190,23 @@
ret.seek(0)
return ret
except ftplib.error_perm, e:
- raise NoSuchFile(self.abspath(relpath), extra=extra)
-
- def put(self, relpath, fp, mode=None):
+ raise NoSuchFile(self.abspath(relpath))
+ except ftplib.error_temp, e:
+ if retries > 1:
+ raise e
+ else:
+ warning("FTP temporary error: %s. Retrying." % str(e))
+ self._FTP_instance = None
+ return self.get(relpath, decode, retries+1)
+ except EOFError, e:
+ if retries > 1:
+ raise e
+ else:
+ warning("FTP connection closed. Trying to reopen.")
+ self._FTP_instance = None
+ return self.get(relpath, decode, retries+1)
+
+ def put(self, relpath, fp, mode=None, retries=0):
"""Copy the file-like or string object into the location.
:param relpath: Location to put the contents, relative to base.
@@ -208,11 +222,25 @@
f.storbinary('STOR '+self._abspath(relpath), fp, 8192)
except ftplib.error_perm, e:
if "no such file" in str(e).lower():
- raise NoSuchFile(msg="Error storing %s: %s"
- % (self.abspath(relpath), str(e)),
- orig_error=e)
+ raise NoSuchFile("Error storing %s: %s"
+ % (self.abspath(relpath), str(e)))
else:
raise FtpTransportError(orig_error=e)
+ except ftplib.error_temp, e:
+ if retries > 1:
+ raise e
+ else:
+ warning("FTP temporary error: %s. Retrying." % str(e))
+ self._FTP_instance = None
+ self.put(relpath, fp, mode, retries+1)
+ except EOFError, e:
+ if retries > 1:
+ raise e
+ else:
+ warning("FTP connection closed. Trying to reopen.")
+ self._FTP_instance = None
+ self.put(relpath, fp, mode, retries+1)
+
def mkdir(self, relpath, mode=None):
"""Create a directory at the given path."""
--
Matthieu
More information about the bazaar
mailing list