--max-transfer - add new exit code (10)

It adds dedicated exit code (10) for --max-duration flag.

Rclone will exit with exit code 10 if the duration limit is reached.

It behaves in similar fashion as --max-transfer and exit code 8.

discussed on the forum:

https://forum.rclone.org/t/max-duration-option-is-triggering-exit-with-error/39917/6
This commit is contained in:
kapitainsky 2023-07-15 17:41:13 +01:00 committed by Nick Craig-Wood
parent 3404eb0444
commit 378a2d21ee
6 changed files with 37 additions and 26 deletions

View File

@ -35,6 +35,7 @@ import (
fslog "github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/rc/rcflags"
"github.com/rclone/rclone/fs/rc/rcserver"
fssync "github.com/rclone/rclone/fs/sync"
"github.com/rclone/rclone/lib/atexit"
"github.com/rclone/rclone/lib/buildinfo"
"github.com/rclone/rclone/lib/exitcode"
@ -501,6 +502,8 @@ func resolveExitCode(err error) {
os.Exit(exitcode.UncategorizedError)
case errors.Is(err, accounting.ErrorMaxTransferLimitReached):
os.Exit(exitcode.TransferExceeded)
case errors.Is(err, fssync.ErrorMaxDurationReached):
os.Exit(exitcode.DurationExceeded)
case fserrors.ShouldRetry(err):
os.Exit(exitcode.RetryError)
case fserrors.IsNoRetryError(err), fserrors.IsNoLowLevelRetryError(err):

View File

@ -1454,14 +1454,14 @@ what will happen.
### --max-duration=TIME ###
Rclone will stop scheduling new transfers when it has run for the
Rclone will stop transferring when it has run for the
duration specified.
Defaults to off.
When the limit is reached any existing transfers will complete.
When the limit is reached all transfers will stop immediately.
Use `--cutoff-mode` to modify this behaviour.
Rclone won't exit with an error if the transfer limit is reached.
Rclone will exit with exit code 10 if the duration limit is reached.
### --max-transfer=SIZE ###
@ -1469,9 +1469,24 @@ Rclone will stop transferring when it has reached the size specified.
Defaults to off.
When the limit is reached all transfers will stop immediately.
Use `--cutoff-mode` to modify this behaviour.
Rclone will exit with exit code 8 if the transfer limit is reached.
### --cutoff-mode=hard|soft|cautious ###
This modifies the behavior of `--max-transfer` and `--max-duration`
Defaults to `--cutoff-mode=hard`.
Specifying `--cutoff-mode=hard` will stop transferring immediately
when Rclone reaches the limit.
Specifying `--cutoff-mode=soft` will stop starting new transfers
when Rclone reaches the limit.
Specifying `--cutoff-mode=cautious` will try to prevent Rclone
from reaching the limit. Only applicable for `--max-transfer`
## -M, --metadata
Setting this flag enables rclone to copy the metadata from the source
@ -1484,20 +1499,6 @@ Add metadata `key` = `value` when uploading. This can be repeated as
many times as required. See the [#metadata](metadata section) for more
info.
### --cutoff-mode=hard|soft|cautious ###
This modifies the behavior of `--max-transfer`
Defaults to `--cutoff-mode=hard`.
Specifying `--cutoff-mode=hard` will stop transferring immediately
when Rclone reaches the limit.
Specifying `--cutoff-mode=soft` will stop starting new transfers
when Rclone reaches the limit.
Specifying `--cutoff-mode=cautious` will try to prevent Rclone
from reaching the limit.
### --modify-window=TIME ###
When checking whether a file has been modified, this is the maximum
@ -2561,6 +2562,7 @@ it will log a high priority message if the retry was successful.
* `7` - Fatal error (one that more retries won't fix, like account suspended) (Fatal errors)
* `8` - Transfer exceeded - limit set by --max-transfer reached
* `9` - Operation successful, but no files transferred
* `10` - Duration exceeded - limit set by --max-duration reached
Environment Variables
---------------------

View File

@ -86,7 +86,7 @@ These flags are available for every command.
--max-delete int When synchronizing, limit the number of deletes (default -1)
--max-delete-size SizeSuffix When synchronizing, limit the total size of deletes (default off)
--max-depth int If set limits the recursion depth to this (default -1)
--max-duration Duration Maximum duration rclone will transfer data for (default 0s)
--max-duration Duration Maximum duration rclone will transfer data for (default off)
--max-size SizeSuffix Only transfer files smaller than this in KiB or suffix B|K|M|G|T|P (default off)
--max-stats-groups int Maximum number of stats groups to keep in memory, on max oldest is discarded (default 1000)
--max-transfer SizeSuffix Maximum size of data to transfer (default off)

View File

@ -20,6 +20,14 @@ import (
"github.com/rclone/rclone/fs/operations"
)
// ErrorMaxDurationReached defines error when transfer duration is reached
// Used for checking on exit and matching to correct exit code.
var ErrorMaxDurationReached = errors.New("max transfer duration reached as set by --max-duration")
// ErrorMaxDurationReachedFatal is returned from when the max
// duration limit is reached.
var ErrorMaxDurationReachedFatal = fserrors.FatalError(ErrorMaxDurationReached)
type syncCopyMove struct {
// parameters
fdst fs.Fs
@ -845,10 +853,6 @@ 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
@ -945,8 +949,8 @@ func (s *syncCopyMove) run() error {
// 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)
fs.Errorf(s.fdst, "%v", ErrorMaxDurationReachedFatal)
s.processError(ErrorMaxDurationReachedFatal)
}
// Print nothing to transfer message if there were no transfers and no errors

View File

@ -996,7 +996,7 @@ func testSyncWithMaxDuration(t *testing.T, cutoffMode fs.CutoffMode) {
accounting.GlobalStats().ResetCounters()
startTime := time.Now()
err := Sync(ctx, r.Fremote, r.Flocal, false)
require.True(t, errors.Is(err, errorMaxDurationReached))
require.True(t, errors.Is(err, ErrorMaxDurationReached))
if cutoffMode == fs.CutoffModeHard {
r.CheckRemoteItems(t, file1)

View File

@ -22,4 +22,6 @@ const (
TransferExceeded
// NoFilesTransferred everything succeeded, but no transfer was made.
NoFilesTransferred
// DurationExceeded is returned when transfer duration exceeded the quota.
DurationExceeded
)