sync: Fix --max-duration so it doesn't retry when the duration is exceeded
Before this change, if the --max-duration limit was reached then rclone would retry the sync as a fatal error wasn't raised. This checks the deadline and raises a fatal error if necessary at the end of the sync. Fixes #6002
This commit is contained in:
parent
251b84ff2c
commit
21355b4208
2 changed files with 15 additions and 4 deletions
|
@ -73,6 +73,7 @@ type syncCopyMove struct {
|
|||
compareCopyDest []fs.Fs // place to check for files to server side copy
|
||||
backupDir fs.Fs // place to store overwrites/deletes
|
||||
checkFirst bool // if set run all the checkers before starting transfers
|
||||
maxDurationEndTime time.Time // end time if --max-duration is set
|
||||
}
|
||||
|
||||
type trackRenamesStrategy byte
|
||||
|
@ -146,9 +147,9 @@ func newSyncCopyMove(ctx context.Context, fdst, fsrc fs.Fs, deleteMode fs.Delete
|
|||
}
|
||||
// If a max session duration has been defined add a deadline to the context
|
||||
if ci.MaxDuration > 0 {
|
||||
endTime := time.Now().Add(ci.MaxDuration)
|
||||
fs.Infof(s.fdst, "Transfer session deadline: %s", endTime.Format("2006/01/02 15:04:05"))
|
||||
s.ctx, s.cancel = context.WithDeadline(ctx, endTime)
|
||||
s.maxDurationEndTime = time.Now().Add(ci.MaxDuration)
|
||||
fs.Infof(s.fdst, "Transfer session deadline: %s", s.maxDurationEndTime.Format("2006/01/02 15:04:05"))
|
||||
s.ctx, s.cancel = context.WithDeadline(ctx, s.maxDurationEndTime)
|
||||
} else {
|
||||
s.ctx, s.cancel = context.WithCancel(ctx)
|
||||
}
|
||||
|
@ -809,6 +810,10 @@ func (s *syncCopyMove) tryRename(src fs.Object) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// errorMaxDurationReached defines error when transfer duration is reached
|
||||
// Used for checking on exit and matching to correct exit code.
|
||||
var errorMaxDurationReached = fserrors.FatalError(errors.New("Max transfer duration reached as set by --max-duration"))
|
||||
|
||||
// Syncs fsrc into fdst
|
||||
//
|
||||
// If Delete is true then it deletes any files in fdst that aren't in fsrc
|
||||
|
@ -902,6 +907,12 @@ func (s *syncCopyMove) run() error {
|
|||
// Read the error out of the context if there is one
|
||||
s.processError(s.ctx.Err())
|
||||
|
||||
// If the duration was exceeded then add a Fatal Error so we don't retry
|
||||
if !s.maxDurationEndTime.IsZero() && time.Since(s.maxDurationEndTime) > 0 {
|
||||
fs.Errorf(s.fdst, "%v", errorMaxDurationReached)
|
||||
s.processError(errorMaxDurationReached)
|
||||
}
|
||||
|
||||
// Print nothing to transfer message if there were no transfers and no errors
|
||||
if s.deleteMode != fs.DeleteModeOnly && accounting.Stats(s.ctx).GetTransfers() == 0 && s.currentError() == nil {
|
||||
fs.Infof(nil, "There was nothing to transfer")
|
||||
|
|
|
@ -1029,7 +1029,7 @@ func TestSyncWithMaxDuration(t *testing.T) {
|
|||
accounting.GlobalStats().ResetCounters()
|
||||
startTime := time.Now()
|
||||
err := Sync(ctx, r.Fremote, r.Flocal, false)
|
||||
require.True(t, errors.Is(err, context.DeadlineExceeded))
|
||||
require.True(t, errors.Is(err, errorMaxDurationReached))
|
||||
|
||||
elapsed := time.Since(startTime)
|
||||
maxTransferTime := (time.Duration(len(testFiles)) * 60 * time.Second) / time.Duration(bytesPerSecond)
|
||||
|
|
Loading…
Reference in a new issue