From 4295428a0f5cdf9fa0d99a2f5fa2dd456ab4cb79 Mon Sep 17 00:00:00 2001 From: Nick Craig-Wood Date: Fri, 16 Mar 2018 21:45:09 +0000 Subject: [PATCH] fs/accounting: add remote control of bwlimit --- docs/content/docs.md | 5 ++++ docs/content/rc.md | 10 ++++++++ fs/accounting/token_bucket.go | 45 +++++++++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/docs/content/docs.md b/docs/content/docs.md index 3872492b8..af80c9986 100644 --- a/docs/content/docs.md +++ b/docs/content/docs.md @@ -306,6 +306,11 @@ running, you can toggle the limiter like this: kill -SIGUSR2 $(pidof rclone) +If you configure rclone with a [remote control](/rc) then you can use +change the bwlimit dynamically: + + rclone rc core/bwlimit rate=1M + ### --buffer-size=SIZE ### Use this sized buffer to speed up file transfers. Each `--transfer` diff --git a/docs/content/rc.md b/docs/content/rc.md index bc45cec02..0e1b8f929 100644 --- a/docs/content/rc.md +++ b/docs/content/rc.md @@ -69,10 +69,20 @@ control commands. ## Supported commands +### core/bwlimit: Set the bandwidth limit. + +This sets the bandwidth limit to that passed in. + +Eg + + rclone core/bwlimit rate=1M + rclone core/bwlimit rate=off + ### cache/expire: Purge a remote from cache Purge a remote from the cache backend. Supports either a directory or a file. Params: + - remote = path to remote (required) - withData = true/false to delete cached data (chunks) as well (optional) diff --git a/fs/accounting/token_bucket.go b/fs/accounting/token_bucket.go index 02787159f..ac8382c09 100644 --- a/fs/accounting/token_bucket.go +++ b/fs/accounting/token_bucket.go @@ -5,6 +5,8 @@ import ( "time" "github.com/ncw/rclone/fs" + "github.com/ncw/rclone/fs/rc" + "github.com/pkg/errors" "golang.org/x/net/context" // switch to "context" when we stop supporting go1.6 "golang.org/x/time/rate" ) @@ -112,3 +114,46 @@ func limitBandwidth(n int) { tokenBucketMu.Unlock() } + +// Remote control for the token bucket +func init() { + rc.Add(rc.Call{ + Path: "core/bwlimit", + Fn: func(in rc.Params) (out rc.Params, err error) { + ibwlimit, ok := in["rate"] + if !ok { + return out, errors.Errorf("parameter rate not found") + } + bwlimit, ok := ibwlimit.(string) + if !ok { + return out, errors.Errorf("value must be string rate=%v", ibwlimit) + } + var bws fs.BwTimetable + err = bws.Set(bwlimit) + if err != nil { + return out, errors.Wrap(err, "bad bwlimit") + } + if len(bws) != 1 { + return out, errors.New("need exactly 1 bandwidth setting") + } + bw := bws[0] + tokenBucketMu.Lock() + tokenBucket = newTokenBucket(bw.Bandwidth) + tokenBucketMu.Unlock() + fs.Logf(nil, "Bandwidth limit set to %v", bw.Bandwidth) + return rc.Params{"rate": bw.Bandwidth.String()}, nil + }, + Title: "Set the bandwidth limit.", + Help: ` +This sets the bandwidth limit to that passed in. + +Eg + + rclone core/bwlimit rate=1M + rclone core/bwlimit rate=off + +The format of the parameter is exactly the same as passed to --bwlimit +except only one bandwidth may be specified. +`, + }) +}