mirror of
https://github.com/rclone/rclone.git
synced 2025-04-11 20:38:24 +02:00
Rework retry logic when copying objects
* Fix off by one retry logic - fixes #406 * Retry any retriable errors * Restructure code
This commit is contained in:
parent
cc6a776034
commit
1b4370bde1
@ -202,11 +202,12 @@ func Copy(f Fs, dst, src Object) {
|
|||||||
maxTries := Config.LowLevelRetries
|
maxTries := Config.LowLevelRetries
|
||||||
tries := 0
|
tries := 0
|
||||||
doUpdate := dst != nil
|
doUpdate := dst != nil
|
||||||
var err, inErr error
|
var err error
|
||||||
tryAgain:
|
var actionTaken string
|
||||||
|
for {
|
||||||
// Try server side copy first - if has optional interface and
|
// Try server side copy first - if has optional interface and
|
||||||
// is same underlying remote
|
// is same underlying remote
|
||||||
actionTaken := "Copied (server side copy)"
|
actionTaken = "Copied (server side copy)"
|
||||||
if fCopy, ok := f.(Copier); ok && src.Fs().Name() == f.Name() {
|
if fCopy, ok := f.(Copier); ok && src.Fs().Name() == f.Name() {
|
||||||
var newDst Object
|
var newDst Object
|
||||||
newDst, err = fCopy.Copy(src, src.Remote())
|
newDst, err = fCopy.Copy(src, src.Remote())
|
||||||
@ -221,11 +222,8 @@ tryAgain:
|
|||||||
var in0 io.ReadCloser
|
var in0 io.ReadCloser
|
||||||
in0, err = src.Open()
|
in0, err = src.Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Stats.Error()
|
err = errors.Wrap(err, "failed to open source object")
|
||||||
ErrorLog(src, "Failed to open: %v", err)
|
} else {
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// On big files add a buffer
|
// On big files add a buffer
|
||||||
if src.Size() > 10<<20 {
|
if src.Size() > 10<<20 {
|
||||||
in0, _ = newAsyncReader(in0, 4, 4<<20)
|
in0, _ = newAsyncReader(in0, 4, 4<<20)
|
||||||
@ -240,21 +238,28 @@ tryAgain:
|
|||||||
actionTaken = "Copied (new)"
|
actionTaken = "Copied (new)"
|
||||||
dst, err = f.Put(in, src)
|
dst, err = f.Put(in, src)
|
||||||
}
|
}
|
||||||
inErr = in.Close()
|
closeErr := in.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = closeErr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tries++
|
||||||
|
if tries >= maxTries {
|
||||||
|
break
|
||||||
}
|
}
|
||||||
// Retry if err returned a retry error
|
// Retry if err returned a retry error
|
||||||
if IsRetryError(err) && tries < maxTries {
|
if IsRetryError(err) || ShouldRetry(err) {
|
||||||
tries++
|
|
||||||
Log(src, "Received error: %v - low level retry %d/%d", err, tries, maxTries)
|
Log(src, "Received error: %v - low level retry %d/%d", err, tries, maxTries)
|
||||||
if removeFailedCopy(dst) {
|
if removeFailedCopy(dst) {
|
||||||
// If we removed dst, then nil it out and note we are not updating
|
// If we removed dst, then nil it out and note we are not updating
|
||||||
dst = nil
|
dst = nil
|
||||||
doUpdate = false
|
doUpdate = false
|
||||||
}
|
}
|
||||||
goto tryAgain
|
continue
|
||||||
}
|
}
|
||||||
if err == nil {
|
// otherwise finish
|
||||||
err = inErr
|
break
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Stats.Error()
|
Stats.Error()
|
||||||
|
Loading…
Reference in New Issue
Block a user