Add support to toggle bandwidth limits via SIGUSR2.

Sending rclone a SIGUSR2 signal will toggle the limiter between off and
the limit set with the --bwlimit command-line option.
This commit is contained in:
Marco Paganini 2016-10-22 00:21:28 -07:00 committed by Nick Craig-Wood
parent 062616e4dd
commit cc4f5ba7ba
4 changed files with 71 additions and 2 deletions

View File

@ -854,6 +854,12 @@ For example to limit bandwidth usage to 10 MBytes/s use `--bwlimit 10M`
This only limits the bandwidth of the data transfer, it doesn't limit This only limits the bandwidth of the data transfer, it doesn't limit
the bandwith of the directory listings etc. the bandwith of the directory listings etc.
For Linux/Unix operating systems: rclone will toggle the bandwidth limiter on
and off upon receipt of the SIGUSR2 signal. This feature allows the user to
remove the bandwidth limitations of a long running rclone transfer during
off-peak hours, and to restore it back to the value specified with --bwlimit
again when needed.
### --checkers=N ### ### --checkers=N ###
The number of checkers to run in parallel. Checkers do the equality The number of checkers to run in parallel. Checkers do the equality

View File

@ -17,8 +17,10 @@ import (
// Globals // Globals
var ( var (
Stats = NewStats() Stats = NewStats()
tokenBucket *tb.Bucket tokenBucket *tb.Bucket
origTokenBucket = tokenBucket
prevTokenBucket = tokenBucket
) )
// Start the token bucket if necessary // Start the token bucket if necessary
@ -27,6 +29,12 @@ func startTokenBucket() {
tokenBucket = tb.NewBucket(int64(bwLimit), 100*time.Millisecond) tokenBucket = tb.NewBucket(int64(bwLimit), 100*time.Millisecond)
Log(nil, "Starting bandwidth limiter at %vBytes/s", &bwLimit) Log(nil, "Starting bandwidth limiter at %vBytes/s", &bwLimit)
} }
origTokenBucket = tokenBucket
prevTokenBucket = tokenBucket
// Start the SIGUSR2 signal handler to toggle bandwidth.
// This function does nothing in windows systems.
startSignalHandler()
} }
// stringSet holds a set of strings // stringSet holds a set of strings
@ -333,6 +341,16 @@ func (acc *Account) read(in io.Reader, p []byte) (n int, err error) {
Stats.Bytes(int64(n)) Stats.Bytes(int64(n))
// Log bandwidth limiter status change.
if tokenBucket != prevTokenBucket {
s := "disabled"
if tokenBucket != nil {
s = "enabled"
}
Log(nil, "Bandwidth limit %s by user", s)
prevTokenBucket = tokenBucket
}
// Limit the transfer speed if required // Limit the transfer speed if required
if tokenBucket != nil { if tokenBucket != nil {
tokenBucket.Wait(int64(n)) tokenBucket.Wait(int64(n))

35
fs/accounting_unix.go Normal file
View File

@ -0,0 +1,35 @@
// Accounting and limiting reader
// Unix specific functions.
// +build darwin dragonfly freebsd linux netbsd openbsd
package fs
import (
"os"
"os/signal"
"syscall"
)
// startSignalHandler() sets a signal handler to catch SIGUSR2 and toggle throttling.
func startSignalHandler() {
// Don't do anything if no bandwidth limits requested.
if bwLimit <= 0 {
return
}
signals := make(chan os.Signal, 1)
signal.Notify(signals, syscall.SIGUSR2)
go func() {
// This runs forever, but blocks until the signal is received.
for {
<-signals
if tokenBucket == nil {
tokenBucket = origTokenBucket
} else {
tokenBucket = nil
}
}
}()
}

10
fs/accounting_windows.go Normal file
View File

@ -0,0 +1,10 @@
// Accounting and limiting reader
// Windows specific functions.
// +build windows
package fs
// startSignalHandler() is Unix specific and does nothing under windows
// platforms.
func startSignalHandler() {}